Aggregations
Combine many items into one result.
reduce()
The Swiss Army knife of aggregations:
import { enumerate } from "jsr:@j50n/proc@0.23.3";
const sum = await enumerate([1, 2, 3, 4])
.reduce((acc, n) => acc + n, 0);
// 10
How It Works
// Start with initial value: 0
// Step 1: 0 + 1 = 1
// Step 2: 1 + 2 = 3
// Step 3: 3 + 3 = 6
// Step 4: 6 + 4 = 10
Building Objects
const grouped = await enumerate(items)
.reduce((acc, item) => {
const key = item.category;
acc[key] = acc[key] || [];
acc[key].push(item);
return acc;
}, {});
Calculating Statistics
const stats = await enumerate(numbers)
.reduce((acc, n) => ({
sum: acc.sum + n,
count: acc.count + 1,
min: Math.min(acc.min, n),
max: Math.max(acc.max, n)
}), { sum: 0, count: 0, min: Infinity, max: -Infinity });
const average = stats.sum / stats.count;
count()
Count items:
const total = await enumerate([1, 2, 3, 4, 5]).count();
// 5
Count Matches
const errorCount = await read("app.log")
.lines
.filter(line => line.includes("ERROR"))
.count();
some()
Check if any item matches:
const hasError = await enumerate(lines)
.some(line => line.includes("ERROR"));
// true or false
Early Exit
Stops as soon as it finds a match:
// Stops reading after first match
const hasLargeFile = await enumerate(files)
.some(file => file.size > 1_000_000_000);
every()
Check if all items match:
const allPositive = await enumerate([1, 2, 3, 4])
.every(n => n > 0);
// true
Validation
const allValid = await enumerate(records)
.every(record =>
record.name &&
record.email &&
record.age >= 0
);
find()
Find first matching item:
const firstError = await enumerate(lines)
.find(line => line.includes("ERROR"));
// First line with ERROR, or undefined
With Complex Predicate
const admin = await enumerate(users)
.find(user =>
user.role === "admin" &&
user.active
);
Real-World Examples
Sum Values
const total = await enumerate(orders)
.map(order => order.amount)
.reduce((sum, amount) => sum + amount, 0);
Count by Category
const counts = await enumerate(items)
.reduce((acc, item) => {
acc[item.category] = (acc[item.category] || 0) + 1;
return acc;
}, {});
Find Maximum
const max = await enumerate(numbers)
.reduce((max, n) => Math.max(max, n), -Infinity);
Build Index
const index = await enumerate(items)
.reduce((acc, item) => {
acc[item.id] = item;
return acc;
}, {});
Concatenate Strings
const combined = await enumerate(words)
.reduce((acc, word) => acc + " " + word, "");
Collect Unique Values
const unique = await enumerate(items)
.reduce((acc, item) => {
acc.add(item);
return acc;
}, new Set());
Advanced Patterns
Running Average
const runningAvg = await enumerate(numbers)
.reduce((acc, n) => {
acc.sum += n;
acc.count += 1;
acc.average = acc.sum / acc.count;
return acc;
}, { sum: 0, count: 0, average: 0 });
Nested Grouping
const grouped = await enumerate(items)
.reduce((acc, item) => {
const cat = item.category;
const type = item.type;
acc[cat] = acc[cat] || {};
acc[cat][type] = acc[cat][type] || [];
acc[cat][type].push(item);
return acc;
}, {});
Frequency Map
const frequency = await enumerate(words)
.reduce((acc, word) => {
acc[word] = (acc[word] || 0) + 1;
return acc;
}, {});
// Find most common
const mostCommon = Object.entries(frequency)
.sort((a, b) => b[1] - a[1])[0];
Accumulate with Transform
const processed = await enumerate(data)
.reduce((acc, item) => {
const transformed = transform(item);
if (transformed.valid) {
acc.push(transformed);
}
return acc;
}, []);
Performance Tips
Use Specific Methods
// ❌ Slower
const count = await enumerate(items)
.reduce((acc) => acc + 1, 0);
// ✅ Faster
const count = await enumerate(items).count();
Early Exit with some/every
// Stops at first match
const hasMatch = await enumerate(huge)
.some(predicate);
// Better than
const matches = await enumerate(huge)
.filter(predicate)
.count();
Combine Operations
// ✅ One pass
const stats = await enumerate(numbers)
.reduce((acc, n) => ({
sum: acc.sum + n,
count: acc.count + 1
}), { sum: 0, count: 0 });
// ❌ Two passes
const sum = await enumerate(numbers).reduce((a, b) => a + b, 0);
const count = await enumerate(numbers).count();
Common Mistakes
Forgetting Initial Value
// ❌ Error with empty array
const sum = await enumerate([]).reduce((a, b) => a + b);
// ✅ Works with empty array
const sum = await enumerate([]).reduce((a, b) => a + b, 0);
Not Returning Accumulator
// ❌ Returns undefined
const result = await enumerate(items)
.reduce((acc, item) => {
acc.push(item);
// Missing return!
}, []);
// ✅ Returns accumulator
const result = await enumerate(items)
.reduce((acc, item) => {
acc.push(item);
return acc;
}, []);
Next Steps
- Transformations - Transform items
- Array-Like Methods - All available methods
- Streaming Large Files - Aggregate huge datasets