使用lodash合并拥有不同键的两个对象数组

5

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

示例

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"
    }
];
4个回答

3
_.map(people, function(p){
    return _.merge(
        p, 
        _.find(data, {number: p.id})
    )
})

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以找到匹配项更好吗?除了将算法的复杂度从线性增加到二次方外,你的解决方案还会改变people中的对象。我唯一看到的优点是你的解决方案隐藏了一些通过Array.prototype.find()实现的复杂性。 - TimoStaudinger
我的解决方案只对所有“数据”进行一次迭代,并执行“Array.find()”。Find将返回与提供的函数匹配的第一个元素。然后设置对象属性并在“合并数组”上进行推送。这就是所需的全部。 - Yosvel Quintero
嗯,没错。但是如果不是通过迭代数组,你认为find()是如何完成其工作的呢? - TimoStaudinger
你是对的 @Timo,你的代码更高效。我正在为所有的 data 做一个 Array.find()。你理解我的意思! - Yosvel Quintero

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 遍历所有的 data,并使用 Array#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; }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接