2016-11-15 203 views
3

我使用Backbone/lodash作为项目,我希望根据特定值合并2个对象数组。在下面的例子中,合并是基于具有2个不同键(id和数字)的相同值。通过加入值用lodash合并2个不同键的对象数组

var people = [ 
    { 
     id: "1", 
     name: "John" 
    }, 
    { 
     id: "2", 
     name: "Jane" 
    } 
]; 

var data = [ 
    { 
     number: "2", 
     role: "Designer" 
    }, 
    { 
     number: "1", 
     role: "Developer" 
    } 
]; 

// Outpout 

var merge = [ 
    { 
     id: "1", 
     number: "1", 
     name: "John", 
     role: "Developer" 
    }, 
    { 
     id: "2", 
     number: "2", 
     name: "Jane", 
     role: "Designer" 
    } 
]; 

回答

1
_.map(people, function(p){ 
    return _.merge(
     p, 
     _.find(data, {number: p.id}) 
    ) 
}) 
1
  • 排序阵列。

  • zipWith将阵列拉到一起。

  • defaults合并每个对象迭代。

var people = [ 
 
    {id: "1", name: "John"}, 
 
    {id: "2", name: "Jane"} 
 
]; 
 

 
var data = [ 
 
    {number: "2", role: "Designer"}, 
 
    {number: "1", role: "Developer"} 
 
]; 
 

 
var result = _.zipWith(
 
    _.sortBy(people, person => person.id), 
 
    _.sortBy(data, dataItem => dataItem.number), 
 
    (person, dataItem) => _.defaults(person, dataItem) 
 
); 
 

 
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.1/lodash.min.js"></script>

0

可以JavaScript来所有dataArray#map()在迭代,并做了Array#find()设置所有p对象属性,其中p.id === d.number

var people = [{id: "1",name: "John"}, {id: "2",name: "Jane"}], 
 
    data = [{number: "2",role: "Designer"}, {number: "1",role: "Developer"}], 
 
    merge = data.map(d => { 
 
     var p = people.find(p => p.id === d.number); 
 
     p.number = d.number; 
 
     p.role = d.role; 
 

 
     return p; 
 
    }); 
 

 
// Outpout 
 
console.log(merge);
.as-console-wrapper { max-height: 100% !important; top: 0; }

2

我不知道lodash函数完全满足此用例。然而,你的目标可以用纯JavaScript和lodash助手_.assign()_.values()可以实现相当不错:

var people = [{id: "1", name: "John"}, {id: "2", name: "Jane"}]; 
 
var data = [{number: "2", role: "Designer"}, {number: "1", role: "Developer"}]; 
 

 
var resultObj = {}; 
 

 
people.forEach(function(item) { 
 
    resultObj[item.id] = item; 
 
}); 
 
data.forEach(function(item) { 
 
    resultObj[item.number] = _.assign({}, resultObj[item.number], item); 
 
}); 
 

 
var result = _.values(resultObj); 
 
console.log(result);
<script src='https://cdn.jsdelivr.net/lodash/4.17.1/lodash.min.js'></script>

+1

@YosvelQuintero它是如何更好地在每个'data'迭代项目,每个项目在'people'上迭代一次以找到匹配的项目?除了这会将算法的复杂性从线性增加到二次方法之外,您的解决方案还会使“人”中的对象发生变化。我看到的唯一优点是您的解决方案隐藏了'Array.prototype.find()'背后的一些复杂性。 – Timo

+0

我的解决方案只对所有'data'进行一次迭代,并执行'Array.find()'。查找将返回与提供的函数匹配的第一个元素。比设置对象属性并对“合并数组”进行推送。这些都需要 –

+0

嗯,是的。但是,如果不通过迭代数组,你认为'find()'是否工作? – Timo