proph3t
proph3t

Reputation: 965

Merge into object array from object by key

My goal is to update an object array by matching an id with another object containing a matching key to update the object array's value key.

Working with an object array like:

const objArr = [
  {
    id: 6,
    name: 'Activity Attendance',
    type: 'Number',
    value: '2000',
    nameChanged: false,
    typeChanged: false,
    internalName: 'activity_attendance'
  },
  {
    id: 123,
    name: 'Total Number of Interacted Consumers',
    type: 'Number',
    value: '400',
    nameChanged: false,
    typeChanged: false,
    internalName: 'total_number_of_interacted_consumers'
  },
  {
    id: 140,
    name: 'Booth Location',
    type: 'Select (Single Answer)',
    value: '',
    nameChanged: false,
    typeChanged: false,
    internalName: 'booth_location'
  }
];

And an object like:

const obj = {
  '6': '1500',
  '123': '180',
  '140': ''
};

Desired outcome:

const objArr = [
  {
    id: 6,
    name: 'Activity Attendance',
    type: 'Number',
    value: '1500',
    nameChanged: false,
    typeChanged: false,
    internalName: 'activity_attendance'
  },
  {
    id: 123,
    name: 'Total Number of Interacted Consumers',
    type: 'Number',
    value: '180',
    nameChanged: false,
    typeChanged: false,
    internalName: 'total_number_of_interacted_consumers'
  },
  {
    id: 140,
    name: 'Booth Location',
    type: 'Select (Single Answer)',
    value: '',
    nameChanged: false,
    typeChanged: false,
    internalName: 'booth_location'
  }
];

I have started down the route of mapping the objArr, but am not sure of how to proceed to make the "match" within obj to get the correct value to update. My failing attempt:

objArr.map(i => i.id.includes(Object.keys(obj).map(o => Number(o))));

How can I can merge into an array of objects from an object?

Upvotes: 1

Views: 61

Answers (5)

stalkert
stalkert

Reputation: 26

You can use the following example to solve your problem:

objArr.forEach(i => i.value = Object.keys(obj).includes(String(i.id)) ? obj[i.id]: i.value);

Upvotes: 0

lealceldeiro
lealceldeiro

Reputation: 14958

You could do it like this (which doesn't modify the original value of objArr):

const result = objArr.map(o => Object.keys(obj).includes(o.id.toString()) ? Object.assign(o, {value: obj[o.id]}) : o);
  • Object.keys(obj).includes(o.id.toString()): check whether in obj is an entry with a key corresponding to an id in objArr (see Object.keys)
  • Object.assign(o, {value: obj[o.id]}) : o): if so, create new a object with the value in objArr, but override value (see Object.assign). If not, return the same object.

Demo:

const objArr = [
  {
    id: 6,
    // ...
    value: '2000'
    // ...
  },
  {
    id: 123,
    // ...
    value: '400'
    // ...
  },
  {
    id: 140,
    // ...
    value: ''
    // ...
  }
];

const obj = {
  '6': '1500',
  '123': '180',
  '140': ''
};

const result = objArr.map(o => Object.keys(obj).includes(o.id.toString()) ? Object.assign(o, {value: obj[o.id]}) : o);

console.log(result);

Upvotes: 0

Andriy
Andriy

Reputation: 15442

Here is solution using map() function and spread (...) operator:

var objArr = [
  {
    id: 6,
    name: 'Activity Attendance',
    type: 'Number',
    value: '2000',
    nameChanged: false,
    typeChanged: false,
    internalName: 'activity_attendance'
  },
  {
    id: 123,
    name: 'Total Number of Interacted Consumers',
    type: 'Number',
    value: '400',
    nameChanged: false,
    typeChanged: false,
    internalName: 'total_number_of_interacted_consumers'
  },
  {
    id: 140,
    name: 'Booth Location',
    type: 'Select (Single Answer)',
    value: '',
    nameChanged: false,
    typeChanged: false,
    internalName: 'booth_location'
  }
];

var obj = {
  '6': '1500',
  '123': '180',
  '140': ''
};

console.log(objArr.map(i => ({
  ...i,
  value: obj[i.id] ? obj[i.id] : i.value 
})))

Upvotes: 1

Mukesh Verma
Mukesh Verma

Reputation: 534

In plain javascript I would do something like this

objArr.forEach(element => {
  let value = obj[parseInt(element.id)];
  if(value){
    element.value = value;
  }
});

Upvotes: 0

Kevin Jantzer
Kevin Jantzer

Reputation: 9451

If you are okay with modifying the original array, this will do the trick:

Just loop through the original object and check if there is an update

objArr.forEach(o=>{
    if( obj[o.id] )
        o.value = obj[o.id]
});

Example:

var objArr = [
  {
    id: 6,
    name: 'Activity Attendance',
    type: 'Number',
    value: '2000',
    nameChanged: false,
    typeChanged: false,
    internalName: 'activity_attendance'
  },
  {
    id: 123,
    name: 'Total Number of Interacted Consumers',
    type: 'Number',
    value: '400',
    nameChanged: false,
    typeChanged: false,
    internalName: 'total_number_of_interacted_consumers'
  },
  {
    id: 140,
    name: 'Booth Location',
    type: 'Select (Single Answer)',
    value: '',
    nameChanged: false,
    typeChanged: false,
    internalName: 'booth_location'
  }
];

var obj = {
  '6': '1500',
  '123': '180',
  '140': ''
};

// loop through the array of objects
objArr.forEach(o=>{

    // see if there is an update in the `obj` var
    if( obj[o.id] )
        o.value = obj[o.id] // apply the update
});

console.log(objArr)

Upvotes: 0

Related Questions