如何在两个对象数组中合并具有相同键的属性?

时间:2019-06-04 12:34:53

标签: javascript arrays

有两个对象数组,其中一些具有相同的键,我想在第一个数组中合并相同的键。我已经粘贴了代码。我使用了嵌套循环,但是性能很差O(n²)。也许我需要另一种方法来提高性能。(由于某种原因我无法使用ES6,因此,如果使用ES5方法,我将不胜感激。)

var people = [
    {
       id: "001",
       name: "David",
       age: 29
    },
    {
       id: "002",
       name: "Lucia",
       age: 41    
    },
    {
       id: "003",
       name: "Steve",
       age: 18
    }
];

var address = [
    {
        id: "001",
        city: "Barcelona"
    },
    {
        id: "002",
        city: "Paris"
    },
    {

    },
    {
        id: "003",
        city: "Tokyo"
    },
    {
        id: "004",
        city: "Barcelona"
    }
];

我的代码

people.forEach(function(item) {
  var id = item.id;
    address.forEach(function(location) {
      if (location.id == id) {
        item.address = location.address
      }
     });
});

结果

var people = [
    {
       id: "001",
       name: "David",
       age: 29,
       city: "Barcelona"
    },
    {
       id: "002",
       name: "Lucia",
       age: 41,
       city: "Paris"    
    },
    {
       id: "003",
       name: "Steve",
       age: 18,
       city: "Tokyo"
    }
];

我更喜欢新的人数组。

5 个答案:

答案 0 :(得分:3)

使用ID作为城市的Map,并在遍历people数组以查找城市时使用它:

let cities = new Map(address.map(a => [a.id, a.city]));
let people2 = people.map(p => ( {...p, city: cities.get(p.id)} ));

答案 1 :(得分:3)

您可以使用一个带有所有地址的Map,然后使用地图的扩展属性来映射新对象。

此方法采用address个对象的所有属性。

var people = [{ id: "001", name: "David", age: 29 }, { id: "002", name: "Lucia", age: 41 }, { id: "003", name: "Steve", age: 18 }],
    address = [{ id: "001", city: "Barcelona" }, { id: "002", city: "Paris" }, {}, { id: "003", city: "Tokyo" }, { id: "004", city: "Barcelona" }],
    map = new Map(address.map(o => [o.id, o])),
    result = people.map(o => Object.assign({}, o, map.get(o.id)));

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

答案 2 :(得分:1)

您可以使用Array#map来迭代people,并使用Array#find在迭代中从id中找到相应的地址:

const people = [{id: "001",name: "David",age: 29 },{ id: "002", name: "Lucia", age: 41
},{ id: "003", name: "Steve", age: 18 }],
  address = [{ id: "001", city: "Barcelona" },{ id: "002", city: "Paris" },{ },{ id: "003", city: "Tokyo" },{ id: "004", city: "Barcelona" }];

console.log(
  people.map(p => ({
    ...p,
    ...address.find(a => (p.id === a.id))
  }))
);

但是,这是假设address项的属性名称与people项的属性名称不同。

答案 3 :(得分:1)

以下代码未经测试,但可以正常工作

// create an object to store them
const mergedItems = {};

// merge the 2 arrays so you only map them once (just for shorter code)
people.concat(address).map(entity => {
  // add each entity on the object and id as a key
  mergedItems[entity.id] = {

    // if the key exist, it will merge it with the new entity
    ...mergedItems[entity.id],
    ...entity,
  }
)

// this is your merged items
// Object.values will convert it from object to array
const finalItems = Object.values(mergedItems);

我使用map而不是for循环,因为它更快:https://codeburst.io/javascript-map-vs-foreach-f38111822c0f

答案 4 :(得分:0)

我已经使用Object.assign方法从地址中添加值

   var people = [{ id: "001", name: "David", age: 29 }, { id: "002", name: "Lucia", age: 41 }, { id: "003", name: "Steve", age: 18 }],
        address = [{ id: "001", city: "Barcelona" }, { id: "002", city: "Paris" }, {}, { id: "003", city: "Tokyo" }, { id: "004", city: "Barcelona" }];

        people.forEach(function(item,pos){
            Object.assign(item,{},address[address.findIndex(o=>o.id == item.id)]);
        });
        console.log(people);