2015-03-28 11 views
8

Ich möchte die _.union Funktion verwenden, um eine Union von zwei Arrays von Objekten zu erstellen. Union arbeitet nur mit Arrays von Primitiven, wenn es === verwendet, um zu prüfen, ob zwei Werte gleich sind.Lodash Union von Arrays von Objekten

Ich möchte Objekte mit einer Schlüsseleigenschaft vergleichen: Objekte mit derselben Schlüsseleigenschaft würden als gleich angesehen werden. Gibt es einen schönen funktionalen Weg, um dies ideal mit lodash zu erreichen?

Antwort

12

Ein nicht rein lodash Weg, dies aber mit der Array.concat Funktion Sie sind in der Lage, dies zu tun entlang uniq() ziemlich einfach zu tun:

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

Ein alternativer Ansatz verwenden flatten() und uniq() wäre:

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

Was ist ein MatcherFn oder Matcher? –

+0

MatcherFn/Matcher ist nur meine Art zu sagen, die Funktion, die Sie schreiben, um festzustellen, ob die Objekte eindeutig sind –

6

Und was ist mit UniqBy mit einem concat der beiden Arrays vor?

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

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

1

lodash zu fusionieren Objekt von Arrays

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

Spät zum par ty aber _.unionWith ist viel besser darin, was du willst.

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 }] 
Verwandte Themen