2015-03-28 17 views
8

Mi piacerebbe utilizzare la funzione _.union per creare un'unione di due matrici di oggetti. L'unione funziona con matrici di primitive solo se usa === per esaminare se due valori sono uguali.Unione Lodash di array di oggetti

Mi piacerebbe confrontare gli oggetti utilizzando una proprietà chiave: gli oggetti con la stessa proprietà chiave sarebbero considerati uguali. C'è un bel modo funzionale per raggiungere quello idealmente usando lodash?

risposta

12

Un modo non pura lodash per fare questo, ma utilizzando la funzione array.concat si è in grado di fare questa bella semplicemente insieme uniq():

var objUnion = function(array1, array2, matcher) { 
    var concated = array1.concat(array2) 
    return _.uniq(concated, false, matcher); 
} 

Un approccio alternativo sarebbe quello di utilizzare flatten() e uniq():

var union = _.uniq(_.flatten([array1, array2]), matcherFn); 
+0

cos'è un Matcher Fn o un matcher? –

+0

matcherFn/matcher è solo il mio modo di dire la funzione che scrivi per determinare se gli oggetti sono unici –

6

E che dire di UniqBy con un concat delle due matrici prima?

_.uniqBy ([{'x': 1}, {'x': 2}, {'x': 1}], 'x');

risultato → [{ 'x': 1}, { 'x': 2}]

1

lodash unire oggetto da array

const test1 = [ 
 
    { name: 'zhanghong', age: 32, money: 0, size: 12, }, 
 
    { name: 'wanghong', age: 20, size: 6 }, 
 
    { name: 'jinhong', age: 16, height: 172 }, 
 
] 
 

 
const test2 = [ 
 
    { name: 'zhanghong', gender: 'male', age: 14 }, 
 
    { name: 'wanghong', gender: 'female', age: 33 }, 
 
    { name: 'lihong', gender: 'female', age: 33 }, 
 
] 
 

 
const test3 = [ 
 
    { name: 'meinv' }, 
 
] 
 

 
const test4 = [ 
 
    { name: 'aaa' }, 
 
] 
 

 
const test5 = [ 
 
    { name: 'zhanghong', age: 'wtf' }, 
 
] 
 

 
const result = mergeUnionByKey(test1, test2, test3, test4, [], test5, 'name', 'override') 
 

 
function mergeUnionByKey(...args) { 
 

 
    const config = _.chain(args) 
 
    .filter(_.isString) 
 
    .value() 
 

 
    const key = _.get(config, '[0]') 
 

 
    const strategy = _.get(config, '[1]') === 'override' ? _.merge : _.defaultsDeep 
 

 
    if (!_.isString(key)) 
 
    throw new Error('missing key') 
 

 
    const datasets = _.chain(args) 
 
    .reject(_.isEmpty) 
 
    .filter(_.isArray) 
 
    .value() 
 

 
    const datasetsIndex = _.mapValues(datasets, dataset => _.keyBy(dataset, key)) 
 

 
    const uniqKeys = _.chain(datasets) 
 
    .flatten() 
 
    .map(key) 
 
    .uniq() 
 
    .value() 
 

 
    return _.chain(uniqKeys) 
 
    .map(val => { 
 
     const data = {} 
 
     _.each(datasetsIndex, dataset => strategy(data, dataset[val])) 
 
     return data 
 
    }) 
 
    .filter(key) 
 
    .value() 
 

 
} 
 

 
console.log(JSON.stringify(result, null, 4))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

2

In ritardo rispetto alla ty ma _.unionWith è molto meglio nel fare quello che vuoi.

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; 
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; 

_.unionWith(objects, others, _.isEqual); 
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] 
Problemi correlati