Aggregators - DarthJDG/Mangler.js GitHub Wiki
The .aggregate() function helps you do calculations on sets of values with the least amount of coding:
Mangler.aggregate(collection, aggregator, options);
Mangler(array).aggregate(aggregator, options);
collectionis any array or iterable object to get the values from.aggregatoris the string identifier of the built-in aggregator function to use. You can also pass your own aggregator function.optionsis an object with optional parameters. If a string or function is passed, it is handled as thevalueoption.
Options:
valueis a string path of a sub-item to use as the value instead of the collection's item. You can pass your own generator function as well.groupis the path of the field to use as a group identifier to process the data in batches. Can also be a custom function that returns the group name.
Simple examples
numbers = [6, 10, 20];
object = { one: 1, two: 2, three: 3 };
// Calculate the sum of an array of numbers
Mangler(numbers).aggregate('+'); // returns 36
// Calculate the sum of object property values
Mangler.aggregate(object, '+'); // returns 6
products = [
{ name: 'cherry', type: 'fruit', price: 3.00 },
{ name: 'orange', type: 'fruit', price: 2.90 },
{ name: 'grapes', type: 'fruit', price: 1.00 },
{ name: 'carrot', type: 'vegetable', price: 2.00 },
{ name: 'celery', type: 'vegetable', price: 3.50 }
];
// Calculate the average product price
Mangler(products).aggregate('avg', 'price'); // returns 2.48
// Collect all product names into an array
Mangler(products).aggregate('[]', 'name');
// returns ['cherry', 'orange', 'grapes', 'carrot', 'celery']
Built-in aggregators
'sum': The sum of all values. Aliases:'+','add''mul': Multiply all values together. Alias:'*''avg': The average of all values.'cnt': The number of values found. Alias:'count''min': The smallest value. Alias:'<''max': The largest value. Alias:'>''array': Returns an array of all values. Alias:'[]'
Grouping
// Count products by type
Mangler(products).aggregate('cnt', { group: 'type' });
// returns object: { fruit: 3, vegetable: 2 }
// Get the lowest prices per product type
Mangler(products).aggregate('min', { value: 'price', group: 'type' });
// returns object: { fruit: 1.00, vegetable: 2.00 }
A custom grouping function takes two parameters (key, item) and returns a group name or identifier, which will become property names of the returned object. key is the array index or object property name of the item within the collection. The following example collects product names grouped by their first letter:
getFirstLetter = function(k, i) { return i.name[0]; };
Mangler(products).aggregate('[]', { value: 'name', group: getFirstLetter });
Returns:
{
c: ['cherry', 'carrot', 'celery'],
g: ['grapes'],
o: ['orange']
}
Custom aggregators
You can pass your own function instead of an aggregator name. The aggregator function gets called for each item in the collection and updates the result. The final result has to be calculated on every call, as there may or may not be further items in the collection. It only needs to generate a single result, grouping of items is handled outside of this function.
It takes three parameters:
kis the key of the item in the collection, either an array index or an object property.vis the value to be processed. Either the item itself, or a part of it extracted by thevalueoption.ais the aggregator object, its value is preserved between aggregator calls. The value ofa.countis the number of values processed so far, including the current one (starts at 1). The result has to be put intoa.result. On the first call,a.resultis undefined.
This is the built-in sum aggregator as an example:
function(k, v, a) {
a.result = a.count === 1 ? v : a.result + v;
}