Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@barneycarroll
Last active August 29, 2015 14:02
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 barneycarroll/e67d36f4fc9430ab2ef6 to your computer and use it in GitHub Desktop.
Save barneycarroll/e67d36f4fc9430ab2ef6 to your computer and use it in GitHub Desktop.
_.superMerge: Like merge, but concatenates plucked arrays (rather than overwriting with the rightmost).
_.mixin( {
// Like uniq, but tests for equivalence rather than identity.
// Does this by running comparison on stringified representations.
// DOM nodes and other objects with circular references can't be stringified and will break.
looseUniq : function uniqBasedOnStringify( source ){
var output = _( source )
.map( function stringify( x ){ return JSON.stringify( x ); } )
.uniq()
.map( function parse( x ){ return JSON.parse( x ); } )
.valueOf();
return output;
},
// Like pluck, but takes an array of keys. eg:
// _.deepPluck( DOMelements, [ 'parentNode', 'parentNode', 'id' ] );
// Useful recurssion wrapper when array is generated programmatically.
deepPluck : function deepPluck( sources, sourceKeys ){
var keys = _.clone( sourceKeys );
return ( function recursivePluck( sources, keys ){
var key = keys.shift();
var candidates = _.filter( sources, function hasKey( source ){ return _.has( source, key ); } );
var pluck = _.pluck( candidates, key );
if( keys.length ){
return recursivePluck( pluck, keys );
}
return pluck;
}( sources, keys ) );
},
// Like merge, but concatenates plucked arrays (rather than overwriting with the rightmost). eg:
// _.superMerge( { a: 1, b: [ 1 , 2 ] }, { c: 3, b: [ 3, 4 ] } ); // => { a: 1, c: 3, b: [ 1, 2, 3, 4 ] };
superMerge : function mergeAndConcatArrays(){
var sources = _.toArray( arguments );
var merge = _.merge.apply( _, [ {} ].concat( sources ) );
void function findArrays( object, path ){
_.each( object, function ( value, key ){
var currentPath = _( path ).clone();
currentPath.push( key );
if( _.isArray( value ) ){
object[ key ] = _( sources )
.deepPluck( currentPath )
.looseUniq()
.flatten( true )
.valueOf();
}
else if( _.isObject( value ) ){
findArrays( value, currentPath );
}
} );
}( merge, [] );
return ( sources[ 0 ] = merge );
}
} );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment