Skip to content

Instantly share code, notes, and snippets.

@robotlolita
Created January 1, 2014 15:19
Show Gist options
  • Save robotlolita/8208773 to your computer and use it in GitHub Desktop.
Save robotlolita/8208773 to your computer and use it in GitHub Desktop.
// Frees the `[].slice` method to accept `this` as the first actual argument,
// rather than a special argument.
var toArray = Function.call.bind([].slice)
// To make searching efficient (O(1)), we switch the
// list of things to a HashMap, which allows we to
// retrieve an item by its name in constant time.
function indexBy(field, list) {
return list.reduce(function(result, item) {
result[item[field]] = item
return result
}, {})
}
// Finally, we want something that for every item in
// the input array, enriches the object with the information
// from the other array
function mergeOn(hashmap, field, list) {
return list.reduce(function(result, item) {
var key = item[field]
return key in hashmap? push(result, extend(hashmap[key], item))
: /* otherwise */ result
}, [])
function push(xs, x){ xs.push(x); return xs }
}
// This just merges a list of objects
function extend(/* ...objects */) {
return toArray(arguments).reduce(function(result, source) {
return Object.keys(source).reduce(function(result, key) {
result[key] = source[key]
return result
}, result)
}, {})
}
// Test
var arr1 = [
{ id: 1, parentId: 34},
{ id: 2, parentId: 35}
];
var arr2 = [
{ id: 34, text: "foo" },
{ id: 35, text: "bar" },
{ id: 36 }
]
mergeOn(indexBy('id', arr2), 'parentId', arr1)
// => [
// { id: 1, parentId: 34, text: "foo" },
// { id: 2, parentId: 35, text: "bar" }
// ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment