Anthony Wang
Anthony Wang

Reputation: 181

How to merge the property with same key in two object array?

There are two object array, some of them have the same key, I'd like to merge the same key in the first array. I have pasted my code.I used nested loop, but the performance was bad O(n²). Maybe I need another method to enhance performance.(I can't use ES6 for some reason, so I'll appreciate if it is the ES5 method.)

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

My code

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

Result

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

The new people array is I preferred.

Upvotes: 1

Views: 324

Answers (5)

Sakthikanth
Sakthikanth

Reputation: 139

I have used Object.assign method to add values from 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" }];

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

Upvotes: 0

I am L
I am L

Reputation: 4652

The code below is not tested but it should work

// 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);

I used map instead of for loop because it is faster: https://codeburst.io/javascript-map-vs-foreach-f38111822c0f

Upvotes: 1

Kévin Bibollet
Kévin Bibollet

Reputation: 3623

You could use Array#map to iterate over people, and Array#find to find the corresponding address from id within iterations:

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))
  }))
);

However, that's supposing that the properties' name of address's items are not the same as people's ones.

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386776

You could take a Map with all addresses and then map new object with extended properties of the map.

This approach takes all properties of address objects.

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

Upvotes: 3

georg
georg

Reputation: 215029

Make a Map with cities by id, and use it when iterating over the people array to find out the city:

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

Upvotes: 3

Related Questions