Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@thiagoh
Last active June 8, 2018 17:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thiagoh/2488bb66b95fdbd4a9431e08260c8659 to your computer and use it in GitHub Desktop.
Save thiagoh/2488bb66b95fdbd4a9431e08260c8659 to your computer and use it in GitHub Desktop.
Map Reduce in JavaScript
Array.prototype.mapReduce = function(keyGrouper, reducer) {
const emit = (key, value) => ({key, value});
const obj = this
.map(value => keyGrouper(emit, value))
.reduce((prev, {key, value}) => {
prev[key] = Array.isArray(prev[key]) ? prev[key] : [];
return prev[key].push(value) && prev;
}, {});
return Object.keys(obj).map(key => reducer(key, obj[key]));
};
const arr = [
{ gender: 'male', country: 'italy', balance: 120},
{ gender: 'male', country: 'usa', balance: 320},
{ gender: 'female', country: 'brazil', balance: 100},
{ gender: 'male', country: 'usa', balance: 80},
{ gender: 'female', country: 'canada', balance: 130},
];
const groupByGenderAndCountry = input => input.mapReduce(
(emit, item) => emit(`${item.gender}-${item.country}`, item.balance),
(key, values) => ({
key,
value: values.reduce((sum, cur) => sum + cur, 0)
})
);
const countByGender = input => input.mapReduce(
(emit, item) => emit(`${item.gender}`, 1),
(key, values) => ({
key,
value: values.reduce((sum, cur) => sum + cur, 0)
})
);
console.log(groupByGenderAndCountry(arr));
// [
// { key: 'male-italy', value: 120 },
// { key: 'male-usa', value: 400 },
// { key: 'female-brazil', value: 100 },
// { key: 'female-canada', value: 130 }
// ]
console.log(countByGender(arr));
// [
// { key: 'male', value: 3 },
// { key: 'female', value: 2 }
// ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment