4

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

2
  • since you want to remove every object from stored array that is not present in the input array, why not just replace the stored array with the input array?
    – Yousaf
    Commented Jul 15, 2020 at 15:46
  • because of courses property in storedArray. They have values which I can't change. If I replace it then the matched objects make all the courses value to 0.
    – Zak
    Commented Jul 15, 2020 at 15:50

3 Answers 3

6

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

4
5

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

Considering that the set of rules results in the newArray being the inputArray in which items courses take the value already in storedArray for corresponding items, a straighforward way to achieve what you want should be something like:

let newArray = inputArray.slice();

for(var i = newArray.length - 1; i >= 0; i--) {
  for(let stored of storedArray) {
    if(stored.name === newArray[i].name){
      newArray[i].courses = stored.courses;
    }
  }
}

[edit]: the concise version of @Yousaf is the way to go.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.