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()
forb
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.