Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to update an array of objects with another array of objects

Tags:

javascript

I have two different arrays of objects, storedArray is stored in my file system and inputArray is made from user's input to update storedArray. The minimum length of each of the array is 1 and there's no cap on the maximum number. Also they doesn't necessarily have to be of the same length. So what I want is to loop over each array and:

  1. if name from inputArray matches with the storedArray name and age is same, then do nothing in the storedArray but keep that object in storedArray. (example John).
  2. if name from inputArray matches with the storedArray name and age is not same, then update only age value in the old object in storedArray. (example Jane).
  3. if there is a new object inside inputArray with a different name that doesn't match with any in storedArray name, then push the new object to storedArray. (example Morris).
  4. Must remove other objects in storedArray which does not match with inputArray. (example Joanna, Jim).

Update this

const storedArray = [
        {"name": "John", "age": 25, "courses": 5},
        {"name": "Jane", "age": 21, "courses": 3},
        {"name": "Joanna", "age": 19, "courses": 2},
        {"name": "Jim", "age": 20, "courses": 4},
];

from this

const inputArray = [
        {"name": "Jane", "age": 23, "courses": 0},
        {"name": "John", "age": 25, "courses": 0},
        {"name": "Morris", "age": 18, "courses": 0}
];

to this:

const storedArray = [
        {"name": "John", "age": 25, "courses": 5},
        {"name": "Jane", "age": 23, "courses": 3},
        {"name": "Morris", "age": 18, "courses": 0}
];

I tried this with for of loop but I get 22 results. And some of them are missing. Moreover, I tried it by pushing it into a new array. There are other posts here in SO with the same titles but the end goal doesn't match with my one. But still I tried their code but doesn't work.

Here's what I tried:

const storedArray = [
        {"name": "John", "age": 25, "courses": 5},
        {"name": "Jane", "age": 21, "courses": 3},
        {"name": "Joanna", "age": 19, "courses": 2},
        {"name": "Jim", "age": 20, "courses": 4}
];

const inputArray = [
        {"name": "Jane", "age": 23, "courses": 0},
        {"name": "John", "age": 25, "courses": 0},
        {"name": "Morris", "age": 18, "courses": 0}
];

let newArray = [];

for(let item of storedArray) {
    for(let each of inputArray) {
        if(item.name === each.name && item.age === each.age){
            newArray.push(item);
        }else if(item.name === each.name && item.age !== each.age) {
            item.age = each.age;
            newArray.push(item);
        }else if(item.name !== each.name){
            newArray.push(each);
            newArray.push(item);
        }
    }
}

console.log(newArray);
like image 961
Zak Avatar asked Sep 13 '25 11:09

Zak


2 Answers

You can use Array#reduce along with Array#find to find the stored matching object. For each element in the input array, we try to find the corresponding element (with the same name) in the stored array. If we do not find one, we push the current element to the accumulator array. Otherwise, we update the age with the age from the input array element before pushing it.

const storedArray = [
        {"name": "John", "age": 25, "courses": 5},
        {"name": "Jane", "age": 21, "courses": 3},
        {"name": "Joanna", "age": 19, "courses": 2},
        {"name": "Jim", "age": 20, "courses": 4},
];
const inputArray = [
        {"name": "Jane", "age": 23, "courses": 0},
        {"name": "John", "age": 25, "courses": 0},
        {"name": "Morris", "age": 18, "courses": 0}
];
const res = inputArray.reduce((acc,curr)=>{
    const stored = storedArray.find(({name})=>name===curr.name);
  if(stored){
    stored.age = curr.age;
    acc.push(stored);
  } else {
    acc.push(curr);
  }
  return acc;
}, []);
console.log(res);
like image 177
Unmitigated Avatar answered Sep 14 '25 23:09

Unmitigated


Instead of updating the storedArray, just update the inputArray.

Map over the inputArray, check if current object from inputArray is present in the storedArray or not. If it exists in the storedArray, update the course property of the current object and return the current object in each iteration.

const storedArray = [
  {"name": "John", "age": 25, "courses": 5},
  {"name": "Jane", "age": 21, "courses": 3},
  {"name": "Joanna", "age": 19, "courses": 2},
  {"name": "Jim", "age": 20, "courses": 4},
];

const inputArray = [
  {"name": "Jane", "age": 23, "courses": 0},
  {"name": "John", "age": 25, "courses": 0},
  {"name": "Morris", "age": 18, "courses": 0}
];

let updatedStoredArr = inputArray.map(a => {
  const exists = storedArray.find(b => a.name == b.name);

  if (exists) {
    a.courses = exists.courses;
  }

  return a;
});

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

You could make the code more concise using ternary operator along with comma operator

let updatedStoredArr = inputArray.map(a => {
  const exists = storedArray.find(b => a.name == b.name);
  return exists ? (a.courses = exists.courses, a) : a;
});
like image 37
Yousaf Avatar answered Sep 15 '25 01:09

Yousaf