以有效的方式合并对象数组

时间:2019-12-18 15:40:42

标签: javascript ecmascript-6

在下面的场景中,我试图合并两个对象数组。

当前代码有效,但是我正在寻找一种更有效的方法。

var constList = [
  { name: "jack", id: "1", designation: "hr" },
  { name: "mary", id: "2", designation: "it" },
  { name: "john", id: "3", designation: "fin" }
]

var apiList = [
  { name: "jack", id: "1", height: "10" },
  { name: "mary", id: "2", height: "20" }
]

var temp = [];

constList.forEach(x => {
  apiList.forEach(y => {
    if (x.id === y.id) {
      temp.push({ ...x,
        ...y
      });
    }
  });
});

console.log(temp);

仅apiList中的匹配元素应与constList合并。

输出正确,任何人都可以用最佳方法指导我。

2 个答案:

答案 0 :(得分:2)

您的解决方案还可以。仅对于非常大列表,您才能受益于创建哈希图所带来的更好的时间复杂性。例如使用Map

let constList = [{ name: "jack", id: "1", designation: "hr" },{ name: "mary", id: "2", designation: "it" },{ name: "john", id: "3", designation: "fin" }]
let apiList = [{ name: "jack", id: "1", height: "10" },{ name: "mary", id: "2", height: "20" }]

let map = new Map(constList.map(o => [o.id, o]));
let result = apiList.map(o => ({...map.get(o.id),...o}));

console.log(result);

这假设apiList从未在id中出现没有的任何constList(这是您在评论中确认的内容)。

这里的时间复杂度是 O(n + m),而不是从嵌套循环中获得的 O(nm)

路口

以上内容假设您确实想进行合并。但是,我确实注意到,在您的代码中您实际上并没有合并,而是采用了 intersection 。如果那是您真正想要的( intersection ),则在上面的代码中反转两个数组的作用,如下所示:

let constList = [{ name: "jack", id: "1", designation: "hr" },{ name: "mary", id: "2", designation: "it" },{ name: "john", id: "3", designation: "fin" }]
let apiList = [{ name: "jack", id: "1", height: "10" },{ name: "mary", id: "2", height: "20" }]

let map = new Map(apiList.map(o => [o.id, o]));
let result = [];
for (let o of constList) {
    let match = map.get(o.id);
    if (match) result.push({...o, ...match});
}

console.log(result);

答案 1 :(得分:0)

您可以使用简单的for循环,如果在某些条件下使用,可能会使性能提高10倍。

我测试了以下代码

测试案例1

算法:您的代码随便使用

输入大小:150个元素(constList = 100个元素和apiList = 50个元素)

输入类型:apiList将始终与constList完全匹配。即apiList的所有50个元素将与constList的100个元素中的50个匹配。

并用您的代码衡量性能,合并和排序结果花了〜0.81ms

测试案例2

算法:以下代码

输入大小:1700个元素(constList = 1000个元素和apiList = 700个元素)

输入类型:apiList将始终与constList完全匹配,即apiList中的所有700个元素将与constList中的700个元素匹配,而1000个元素中将不匹配。

并使用以下代码测量性能,合并结果并对其进行排序花了〜0.82ms

for(let i =0; i< constList.length;i++){
    flag = true;
    for(let j=0; j<apiList.length;j++){
        if(apiList[j].id == constList[i].id){
            const data = Object.assign({}, constList[i], apiList[j]);
            temp.push(data);
            flag = false;
            apiList.splice(j,1);
            break;
        }
    }
    flag && temp.push(constList[i]) && constList.splice(i,1);
}

注意:此处,由于删除操作,原始阵列将被更改。因此,请确保仅对克隆/重复阵列执行该操作以保留原始数据。