I am facing one problem with array destructuring, Please read my questions-
This is array 1-
const Array1 = [
{
label: "Fashion",
value: 1
},
{
label: "Electronics",
value: 2
}
]
This is array2-
const Array2 = [
{
id: 1,
values: [
{ value: "S", meta: "s" },
{ value: "M", meta: "m" },
{ value: "Xl", meta: "xl" },
]
},
{
id: 2,
values: [
{ value: "Red", meta: "red" },
{ value: "Yellow", meta: "yellow" },
{ value: "Green", meta: "green" },
]
}
]
I have to combine this two array when Id(array2)
matched to value(array1)
and also change field label- like I need actually like this-
const Array3 = [
{
name: "Fashion",
options: [
{ value: "S", label: "s" },
{ value: "M", label: "m" },
{ value: "Xl", label: "xl" },
]
},
{
name: "Electronics",
options: [
{ value: "Red", label: "red" },
{ value: "Yellow", label: "yellow" },
{ value: "Green", label: "green" },
]
}
]
I have already tried in this way-
const Array3 = Array1.map((item) => {
return {
name: item.label,
values: [],
options: Array2.map((e: any) => {
if (e.id === item.value) {
return e.values.map((v: any) => {
return {
label: v.meta,
value: v.value
}
})
}
})
}
})
From this function I am getting - one extra field with undefined
-
But it's not working. Please help me by giving a correction of my functions.
CodePudding user response:
You could take an object for the names and map new objects with name
instead of id
as properties.
const
array1 = [{ label: "Fashion", value: 1 }, { label: "Electronics", value: 2 }],
array2 = [{ id: 1, values: [ { value: "S", meta: "s" }, { value: "M", meta: "m" }, { value: "Xl", meta: "xl" }] }, { id: 2, values: [{ value: "Red", meta: "red" }, { value: "Yellow", meta: "yellow" }, { value: "Green", meta: "green" }] }],
names = Object.fromEntries(array1.map(({ label, value }) => [value, label])),
result = array2.map(({ id, values }) => ({
name: names[id],
options: values.map(({ meta: label, ...o }) => ({ ...o, label }))
}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
The reason why Array2.map
doesn't work is that map function always returns the same number of elements as the array you run .map
on. So adding a condition results in undefined elements when condition doesn't match. You can do this:
options: Array2.find(e => e.id === item.value).values.map(v => {
return { value: v.value, label: v.meta }
})
While this works, I'd recommend taking a look at @Nina Scholz's answer too as it makes use of Object/Dictionary which is much more efficient than running .find
on Array2. O(1) vs O(n). So, if you expect to have lots of elements in Array2 or run this quite frequently then the more efficient solution would help
CodePudding user response:
Maybe this is what you want?
const Array3 = Array1.map(array1Item => {
const foundIndex = Array2.findIndex(array2Item => array2Item.id === array1Item.value);
if(foundIndex !== -1) {
return {
name: array1Item.label,
options: Array2[foundIndex].values
}
};
return undefined;
});
console.log(Array3);
/**
[{
name: "Fashion"
options: Array(3)
0: {value: 'S', meta: 's'}
1: {value: 'M', meta: 'm'}
2: {value: 'Xl', meta: 'xl'}
},{
name: "Electronics"
options: Array(3)
0: {value: 'Red', meta: 'red'}
1: {value: 'Yellow', meta: 'yellow'}
2: {value: 'Green', meta: 'green'}
}]
*/