combine specific properties of array of objects

Viewed 68

add default value for basis 'Default' if not available in second array when combined

var arrayOne = [{id: 1, name: 'A'},{id:2, name: 'B'},{id:3, name: 'C'},{id:4, name: 'D'},{id:5, name: 'E'}];
var arrayTwo = [{id: 1, basis: 'Online'},{id:3, basis: 'Paper'},{id:4, basis: 'Referrer'}];

One Result should be:

var combinedArray = [{id: 1, name: 'A', basis: 'Online'},{id:2, name: 'B', basis: 'Default'},{id:3, name: 'C', basis: 'Paper'},{id:4, name: 'D', basis: 'Referrer'},{id:5, name: 'E', basis: 'Default'}];

can we get other result of array which deletes name from fist array as below

var combinedArray2 = [{id: 1, basis: 'Online'},{id:2, basis: 'Default'},{id:3, basis: 'Paper'},{id:4, basis: 'Referrer'},{id:5, basis: 'Default'}];

I tried

var combinedArray = []; 
arrayOne.forEach(objOne => {
  arrayTwo.forEach(objTwo => {
    if(objOne.id === ObjTwo.id){
      combinedArray.push({...objOne,...objTwo});
    }
  });
});

Is there any easy way and faster way to get resulted array without iterating two times with improved performance

6 Answers

Another way is create a Map of the basis values using id as keys and look up those values in a mapping of the first array

const bMap = new Map(arr2.map(e => [e.id, e.basis]))

const res = arr1.map(e => ({...e, basis : bMap.get(e.id) || 'Default' }))

console.log(res)
<script>
var arr1 = [{id: 1, name: 'A'},{id:2, name: 'B'},{id:3, name: 'C'},{id:4, name: 'D'},{id:5, name: 'E'}];
var arr2 = [{id: 1, basis: 'Online'},{id:3, basis: 'Paper'},{id:4, basis: 'Referrer'}];
</script>

Here is another way to do this:

var arrayOne = [{id: 1, name: 'A'},{id:2, name: 'B'},{id:3, name: 'C'},{id:4, name: 'D'},{id:5, name: 'E'}];
var arrayTwo = [{id: 1, basis: 'Online'},{id:3, basis: 'Paper'},{id:4, basis: 'Referrer'}];

function groupArrays(arr1, arr2){
     return arr1.map(e => {
          let element = arr2.find(elem=>elem.id==e.id);
          e['basis'] = element?element['basis']:'Default';
          return e;
     });
}

console.log(groupArrays(arrayOne, arrayTwo));

Complexity of O(constant * n) ~ O(n) (with n is the length of the concatenated array)

const arrayOne = [
  { id: 1, name: "A" },
  { id: 2, name: "B" },
  { id: 3, name: "C" },
  { id: 4, name: "D" },
  { id: 5, name: "E" },
]
const arrayTwo = [
  { id: 1, basis: "Online" },
  { id: 3, basis: "Paper" },
  { id: 4, basis: "Referrer" },
]

const lookup = {}
const concatArray = arrayOne.concat(arrayTwo)
concatArray.forEach((obj) => {
  lookup[obj.id] = { id: obj.id, ...lookup[obj.id], basis: "Default", ...obj }
})

const res = Object.values(lookup)

console.log(res)

In O(n+m) time complexity and O(n+m) space complexity.

var arrayOne = [{id: 1, name: 'A'},{id:2, name: 'B'},{id:3, name: 'C'},{id:4, name: 'D'},{id:5, name: 'E'}];
var arrayTwo = [{id: 1, basis: 'Online'},{id:3, basis: 'Paper'},{id:4, basis: 'Referrer'}];

var obj = {};
arrayOne.forEach(({id, name}) => {
    obj[id] = {id, name, basis: 'Default'};
});

arrayTwo.forEach(({id, basis}) => {
    obj[id].basis = basis;
});

let result = Object.values(obj);
console.log(result);

Here is a solution that can do both.

var arrayOne = [{id: 1, name: 'A'},{id:2, name: 'B'},{id:3, name: 'C'},{id:4, name: 'D'},{id:5, name: 'E'}];
var arrayTwo = [{id: 1, basis: 'Online'},{id:3, basis: 'Paper'},{id:4, basis: 'Referrer'}];

var combinedArray = arrayOne.map(({id, name, basis = 'Default'}) => {
    arrayTwo.some(obj => (obj.id == id) && (basis = obj.basis));
    return { id, name, basis }; //With Name
    // return { id, basis }; //Without Name
});

console.log(combinedArray);
// var combinedArray = [{id: 1, name: 'A', basis: 'Online'},{id:2, name: 'B', basis: 'Default'},{id:3, name: 'C', basis: 'Paper'},{id:4, name: 'D', basis: 'Referrer'},{id:5, name: 'E', basis: 'Default'}];

if there is only one object for each id in the second array you can

var combinedArray = arrayOne.map(objOne => {
  let objTwo = arrayTwo.find(objTwo => {
    return objTwo.id === objOne.id
  });
  return {
    basis: 'default',
    ...objOne,
    ...objTwo
  }
});
Related