Home > Mobile >  Compare two arrays of objects and merge some fields
Compare two arrays of objects and merge some fields

Time:12-06

I'm working with Angular and RxJs and I have two arrays of objects. I need to change one specific field of the first array, if the second one has the field with the same value (all of the four fields has different names). I did it with nested loops, but I need to find a better solution, my code is down below

My solution is working, but it's not the best, because arrays can be really large - so the code will work slow. If there's 1000 items in each array, it will be 1000000 iterations - that's why I need to find a better solution. I got advice to use multiple consecutive loops, but I don't really get how to use it here

this.api
  .getFirstArray()
  .pipe(
    mergeMap((firstArray) =>
      this._secondApi.getSecondArray().pipe(
        map((secondArray) => {
          for (const item2 of secondArray) {
            for (const item1 of firstArray) {
              if (item1.someField === item2.otherField)
                item1.someOtherField = item2.anotherField;
            }
          }

          return firstArray;
        }),
      ),
    ),
  )
  .subscribe((value) => {
    this.gridApi?.setRowData(value);
  });

So for example my data is

 firstArray: [
    { id: 445; name: 'test' },
    { id: 4355; name: 'test1' },
    { id: 234_234; name: 'test2' },
  ];

secondArray: [
    { firstName: 'test3'; newId: 445 },
    { firstName: 'test5'; newId: 2 },
    { firstName: 'test6'; newId: 234_234 },
  ];

And the result should be

result: [{ id: 445; name: 'test3' }, { id: 4355; name: 'test1' }, { id: 234_234; name: 'test6' }];

Note: the ids of the first array objects may be repeated - all of the objects names need to be updated

CodePudding user response:

here is the working example of your problem, may be it will help you.

 let firstArray = [
    { id: 445, name: 'test' },
    { id: 4355, name: 'test1' },
    { id: '234_234', name: 'test2' },
  ];

let secondArray = [
    { firstName: 'test3', newId: 445 },
    { firstName: 'test5', newId: 2 },
    { firstName: 'test6', newId: '234_234' },
  ];
  

secondArray.forEach(sec => {
  let see = firstArray.findIndex(first => first.id === sec.newId);
  if (see > -1) {
    firstArray[see].name = sec.firstName
  }
})

console.log(firstArray)

CodePudding user response:

You still end up with O(N²) complexity (there are two nested loops that he wants to avoid).

Instead, You can use map

const firstArray = [
  { id: 445, name: 'test' },
  { id: 4355, name: 'test1' },
  { id: '234_234', name: 'test2' },
];

const secondArray = [
  { firstName: 'test3', newId: 445 },
  { firstName: 'test5', newId: 2 },
  { firstName: 'test6', newId: '234_234' },
];

const secondMap = new Map();

secondArray.forEach((item) => {
  secondMap.set(item.newId, item.firstName);
});

for (const item of firstArray) {
  if (secondMap.has(item.id)) {
    item.name = secondMap.get(item.id);
  }
}

console.log(firstArray)
  • Related