Skip to content

Instantly share code, notes, and snippets.

@danse
Last active August 29, 2015 14:09
Show Gist options
  • Save danse/74459f19101dadd9831e to your computer and use it in GitHub Desktop.
Save danse/74459f19101dadd9831e to your computer and use it in GitHub Desktop.
map reduce for Couch statistics
var a = {
place: 'europe',
animal: 'dog'
},
b = {
animal: 'dog'
},
c = {
place: 'africa'
},
d = {
place: 'africa',
animal: 'dog'
}
e = {
place: 'africa',
animal: 'cat'
};
function reduce(keys, values, rereduce) {
function setDefault(obj, key, value) {
if (!(key in obj)) {
obj[key] = value;
}
}
function setOrSum(obj, key, value) {
obj[key] = obj[key] ? obj[key] + value : value;
};
function doubleSetOrSum(value1, value2, obj, key) {
setDefault(obj, key, {});
setDefault(obj[key], value1, {});
setOrSum(obj[key][value1], value2, 1);
}
function add(value, stats) {
setOrSum(stats, value.animal, 1);
doubleSetOrSum(value.place, value.animal, stats, 'place');
}
function forKeyIn(obj, fun) { Object.getOwnPropertyNames(obj).forEach(fun); }
function merge(stat, merged) {
forKeyIn(stat, function(key) {
if (typeof stat[key] === 'number') {
setOrSum(merged, key, stat[key]);
} else {
setDefault(merged, key, {});
forKeyIn(stat[key], function(key2) {
setOrSum(merged[key], key2, stat[key][key2]);
});
}
});
}
function accumulate(arr, fun, accumulator) {
arr.forEach(function(el) {
fun(el, accumulator);
});
return accumulator;
}
var fun = rereduce ? merge : add;
return accumulate(values, fun, {});
}
var test = reduce(null, [reduce(null, [a, b]), reduce(null, [c, d, e])], true);
require('assert').deepEqual(test, {"dog":3,"place":{"europe":{"dog":1},"undefined":{"dog":1},"africa":{"dog":1,"cat":1, "undefined":1}},"cat":1, "undefined":1});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment