// mapper should return an array of [{key:'somekey', value:'somevalue'}]
// reducer should return a single {key:'somekey', value:'somevalue'}
function mapReduce(i, mapper, reducer, property) {
var intermediate = [];
var output = [];
if(i && i.constructor == Array)
{
for(var x = 0; x < i.length; x++)
{
var value = i[x][property];
var key = property;
intermediate = intermediate.concat(mapper(key, value));
}
}
else
{
for (var key in i)
{
var value = i[key];
intermediate = intermediate.concat(mapper(key, value));
}
}
var groups = groupBy(intermediate);
for (var key in groups)
{
var values = groups[key];
output.push(reducer(key, values));
}
return output;
}
// list should be [{key:k, value:v}, ....] where key may be repeated.
// returns [{key, [v1, v2, v3...]}, ...] where key is *not* repeated.
function groupBy(list) {
var ret = {};
for (var i = 0; i < list.length; i++) {
var key = list[i].key;
var value = list[i].value;
if (!ret[key]) {
ret[key] = [];
}
ret[key].push(value);
}
return ret;
}