Home > OS >  How to push array of objects to a new array variable inside another object inside array by value?
How to push array of objects to a new array variable inside another object inside array by value?

Time:04-16

I have 2 array that consist object :

a = 
[
 {
  id: 105647,
  name: 'name1'
 },
 {
  id: 105941,
  name: 'name2'
 },
 {
  id: 106177,
  name: 'name3'
 }
]

b = 
[
 [
  {
   id: 105647,
   transactionDate: '2022-03-21',
   order: 1
  },
  {
   id: 105647,
   transactionDate: '2022-03-22',
   order: 2
  }
 ],
 [
  {
   id: 106177,
   transactionDate: '2022-03-24',
   order: 1
  },
 ]
]

As you can see, that in b is not always have data for each id in variable a.

And my desired output would be

a = 
[
 {
  id: 105647,
  name: 'name1',
  dataB:
   [
    {
     id: 105647,
     transactionDate: '2022-03-21',
     order: 1
    },
    {
     id: 105647,
     transactionDate: '2022-03-22',
     order: 2
    }
   ]
 },
 {
  id: 105941,
  name: 'name2'
 },
 {
  id: 106177,
  name: 'name3',
  dataB: 
   [
    {
     id: 106177,
     transactionDate: '2022-03-24',
     order: 1
    },
   ]
  }
]

the b variable should be pushed to new variable dataB inside object of array on variable a. And if no dataB exist on a it would not create dataB on a / create the dataB but with empty array.

I was already try with some

for (let i = 0; i<a.length; i  ) {
  a[i]['dataB'] = b[i]
}

the result is not pushed by id, but by index. The problem is b not always have data for each id in variable a. And what i'm trying was not what i looking for.

Please ask me if you need more information if it's still not enough to solve that case.

CodePudding user response:

loop thought a array,

on each iteration find all matches

if array is not empty - assign it to new field dataB

    const a = 
    [
     {
      id: 105647,
      name: 'name1'
     },
     {
      id: 105941,
      name: 'name2'
     },
     {
      id: 106177,
      name: 'name3'
     }
    ]

    const b = 
[
 [
  {
   id: 105647,
   transactionDate: '2022-03-21',
   order: 1
  },
  {
   id: 105647,
   transactionDate: '2022-03-22',
   order: 2
  }
 ],
 [
  {
   id: 106177,
   transactionDate: '2022-03-24',
   order: 1
  },
 ]
];

    const result = a.map(i => {
    const foundTrancactions = b.flat().filter(el => el.id === i.id);
return {...i, ...(foundTrancactions?.length ? {dataB: foundTrancactions} : {})}
    })

    console.log(result)

UPDATE

  • have changed b array
  • added flat() for b

CodePudding user response:

If your goal is to modify a, as opposed to creating a new array, you can use Array#forEach and Array#filter methods as follows:

const a = [ { id: 105647, name: 'name1' }, { id: 105941, name: 'name2' }, { id: 106177, name: 'name3' } ]; 
const b = [ [ { id: 105647, transactionDate: '2022-03-21', order: 1 }, { id: 105647, transactionDate: '2022-03-22', order: 2 } ], [ { id: 106177, transactionDate: '2022-03-24', order: 1 }, ] ];

a.forEach((elA,i) => {
    const others = b.filter(elB => elB.every(o => o.id === elA.id)).flat();
    a[i] = others.length ? {...elA, dataB: others} : elA;
});

console.log( a );

Since in b the items are already grouped by id, Array#find may be a better method, and will not need the use of Array#flat:

const a = [ { id: 105647, name: 'name1' }, { id: 105941, name: 'name2' }, { id: 106177, name: 'name3' } ]; 
const b = [ [ { id: 105647, transactionDate: '2022-03-21', order: 1 }, { id: 105647, transactionDate: '2022-03-22', order: 2 } ], [ { id: 106177, transactionDate: '2022-03-24', order: 1 }, ] ];

a.forEach((elA,i) => {
    const others = b.find(elB => elB.every(o => o.id === elA.id));
    a[i] = others ? {...elA, dataB: others} : elA;
    /*OR: you can replace the above one line with the following 3
    if( others ) {
        a[i].dataB = others;
    }*/
});

console.log( a );

CodePudding user response:

This solution is non-mutating and employs the idea shared by Barmar in comments above.

Code Snippet

const getTransformedArray = (orig, delta) => {
  // first, construct a key-value pair using "b" array (called "delta" here)
  const deltaMap = delta.reduce(
    (acc, itm) => ({
      ...acc,         // retain existing results from "acc" (accumulator)
      [itm.id]: (
        acc[itm.id] || []       // if "itm.id" already exists, keep its array
      ).concat([{...itm}])      // append the current "itm"
    }),
    {}                // "acc" is initially set to empty object "{}"
  );
  // now, iterate through "a" array (named "orig" here)
  return orig.map(
    ({id, name}) => ({    // de-structure to directly access "id", "name" props
      id, name,           // retain "id", "name"
      ...(                // add new prop "dataB" only if it's in deltaMap
        id in deltaMap
        ? { dataB: deltaMap[id] }
        : {}              // if no matching "id" in "deltaMap", don't add "dataB"
      )
    })
  );
};


const a = 
[
 {
  id: 105647,
  name: 'name1'
 },
 {
  id: 105941,
  name: 'name2'
 },
 {
  id: 106177,
  name: 'name3'
 }
]

const b = 
[
 {
  id: 105647,
  transactionDate: '2022-03-21',
  order: 1
 },
 {
  id: 105647,
  transactionDate: '2022-03-22',
  order: 2
 },
 {
  id: 106177,
  transactionDate: '2022-03-24',
  order: 1
 },
];

// invoke the transform function
console.log('transformed array: ', getTransformedArray(a, b));

// display "a" and "b" arrays to show those were not mutated
console.log('original a: ', a);
console.log('original b: ', b);
.as-console-wrapper { max-height: 100% !important; top: 0 }

Explanation

Inline comments provided in the snippet above.

  • Related