2

Have first array (a) and second with updated values (b). Need to update matching by IDs objects and get result array (c). How can I make it simple and fast?

let a = [
    { id: 1, activated: '0' },
    { id: 2, activated: '0' },
    { id: 3, activated: '0' },
    { id: 4, activated: '0' },
  ]
let b = [
    { id: 2, activated: '1' },
    { id: 3, activated: '1' },
  ]
//Result array:
c = [ 
  { id: 1, activated: '0' },
  { id: 2, activated: '1' },
  { id: 3, activated: '1' },
  { id: 4, activated: '0' },
]
2
  • Do you want to merge the arrays ordering them by ID? Commented Aug 11, 2020 at 21:40
  • What did you try? Please read topics at StackOverflow.com/help for more info about requirements for asking questions on SO. Commented Aug 12, 2020 at 7:36

7 Answers 7

2

I recommend you to create an object where keys are the ids for fast access.

With the newly created object you can access the specific objects from b using the id as key and update the objects.

Finally, get the array c using the function Object.values.

This is assuming that b has ids that exist in a.

let a = [    { id: 1, activated: '0' },    { id: 2, activated: '0' },    { id: 3, activated: '0' },    { id: 4, activated: '0' }]
let b = [    { id: 2, activated: '1' },    { id: 3, activated: '1' }];
let newA = a.reduce((a, {id, ...rest}) => ({...a, ...{[id]: {id, ...rest}}}), {});

b.forEach(({id, activated}) => newA[id].activated = activated);

let c = Object.values(newA);
console.log(c);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

2 Comments

Great, Thank you!
@МаксимЮрченко yw!
1

You can use Array.map, then foreach object, you can use Array.find to check if it exist in arrayB by ID and return if it does.

let a = [
    { id: 1, activated: '0' },
    { id: 2, activated: '0' },
    { id: 3, activated: '0' },
    { id: 4, activated: '0' },
];

let b = [
    { id: 2, activated: '1' },
    { id: 3, activated: '1' },
];

const c = a.map(e => {
    let newValue = b.find(n => e.id === n.id);

    if (!!newValue) {
        return newValue;
    }

    return e;
});

Comments

1

This is how I would approach it:

function mergeArray(...toMerge) {
  let output = {};
  toMerge.forEach(arr => {
    arr.forEach(item => {
      output[item.id] = item;
    });
  });
  return Object.values(output);
}

let a = [
    { id: 1, activated: '0' },
    { id: 2, activated: '0' },
    { id: 3, activated: '0' },
    { id: 4, activated: '0' },
  ];
let b = [
    { id: 2, activated: '1' },
    { id: 3, activated: '1' },
  ];

console.dir(mergeArray(a, b)) // can merge n-number of arrays.

Comments

0
let c = a.map( aObj => {
  let found = b.find(bObj => bObj.id === aObj.id);
    if(found) return found;
    else return aObj;
});

Comments

0

You could create a map of the second array, keyed by id, and then when you make a copy of a objects into c, use that map to merge matching b objects into them.

let a = [{ id: 1, activated: '0' },{ id: 2, activated: '0' },{ id: 3, activated: '0' },{ id: 4, activated: '0' }]
let b = [{ id: 2, activated: '1' },{ id: 3, activated: '1' }];

let map = new Map(b.map(o => [o.id, o]));
let c = a.map(o => ({...o, ...map.get(o.id)}));

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

Comments

0

Building a hash from the ids of array a. Iterate over array b by looking in the hash for the index b.id, if found actualisize in a with the founded index the property activated. Otherwise (in example id: 5) there don't exists in the old array a for this id an entry so create a new one and actualisize the hash.

let a = [
    { id: 1, activated: '0' },
    { id: 2, activated: '0' },
    { id: 3, activated: '0' },
    { id: 4, activated: '0' },
  ];
let b = [
    { id: 2, activated: '1' },
    { id: 3, activated: '1' },
    { id: 5, activated: '0' },
  ];

let hash = a.flatMap(el => el.id);

b.forEach(elem => {
    index = hash.indexOf(elem.id);
    if (index!=-1) 
        a[index].activated=elem.activated;
     else {
        a.push(elem);
        hash.push(elem.id);
     }
});
  
console.log(a);  

Comments

-1

Try this

let a = [{
    id: 1,
    activated: '0'
  },
  {
    id: 2,
    activated: '0'
  },
  {
    id: 3,
    activated: '0'
  },
  {
    id: 4,
    activated: '0'
  },
]
let b = [{
    id: 2,
    activated: '1'
  },
  {
    id: 3,
    activated: '1'
  },
]
//Result array:
c = [{
    id: 1,
    activated: '0'
  },
  {
    id: 2,
    activated: '1'
  },
  {
    id: 3,
    activated: '1'
  },
  {
    id: 4,
    activated: '0'
  },
]

let result = a.map(e => {
  let p = b.find(be => be.id === e.id)
  if (p) e.activated = p.activated;
  return e
})

console.log(result)

2 Comments

can anybody explain why this would be not ideal solution? im curious to know about perf optimisation.
Not my downvote, but find represents a loop, and so you have a nested loop giving a total time complexity of O(n²), while this can be done in linear time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.