2015-03-28 6 views
8

Chciałbym użyć funkcji _.union, aby utworzyć połączenie dwóch tablic obiektów. Union pracuje z tablicami prymitywów tylko wtedy, gdy używa === do sprawdzenia, czy dwie wartości są równe.Zlot lodu z tablic obiektów

Chciałbym porównać obiekty za pomocą właściwości klucza: obiekty o tej samej właściwości klucza będą traktowane jako równe. Czy istnieje przyjemny, funkcjonalny sposób, aby osiągnąć to idealnie używając lodash?

Odpowiedz

12

Non czysty lodash sposobem, aby to zrobić, ale przy użyciu funkcji Array.concat jesteś w stanie to zrobić bardzo prosto wzdłuż uniq():

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

Alternatywnym rozwiązaniem byłoby wykorzystanie flatten() i uniq():

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

co to jest matcherFn lub matcher? –

+0

MatcherFn/Matcher to po prostu mój sposób powiedzenia funkcji, którą piszesz, aby określić, czy obiekty są unikatowe –

6

A co z UniqBy z konkat z dwóch tablic przed?

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

wynik → [{x '1}, {x' 2}]

1

lodash połączyć obiekt z tablic

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

Późno do normy ty ale _.union Z dużo lepszym robieniem tego, co chcesz.

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