How to can I do this array desctructure with condition? - javascript

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-
Please click to see
But it's not working. Please help me by giving a correction of my functions.

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; }

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

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'}
}]
*/

Related

combine array of object if atleast one property is common

//this one is actual array
const data = [
{
name: 'shanu',
label: 'ak',
value: 1,
},
{
name: 'shanu',
label: 'pk',
value: 2,
},
{
name: 'bhanu',
label: 'tk',
value: 3,
},
];
>
//and this is the array that I want
let outPut =
[
{
name:'shanu',
label:['ak','pk'],
value:[1,2]
},
{
name:'bhanu',
label:['tk'],
value:[3]
}
]
You can use Array.prototype.reduce() like this:
const data = [
{
name: 'shanu',
label: 'ak',
value: 1,
},
{
name: 'shanu',
label: 'pk',
value: 2,
},
{
name: 'bhanu',
label: 'tk',
value: 3,
},
];
const output = data.reduce((prev, curr) => {
const tmp = prev.find((e) => e.name === curr.name)
if (tmp) {
tmp.label.push(curr.label)
tmp.value.push(curr.value)
} else {
prev.push({
name: curr.name,
label: [curr.label],
value: [curr.value],
})
}
return prev
}, [])
console.log(output)

create an new array of objects from two array of objects in vanilla JS

I have two array of objects:
watches = [
{
id: "1",
label: "Rolex",
color: "UUID_OF_SILVER",
},
{
id: "2",
label: "Omega",
color: "UUID_OF_BLACK",
},
{
id: "3",
label: "Zenith",
color: "UUID_OF_SILVER",
},
];
watch_colors = [
{
id: "UUID_OF_BLACK",
label: "Black",
},
{
id: "UUID_OF_SILVER",
label: "Silver",
},
];
Now I need to print this in console using vanilla JS
Rolex Silver
Omega Black
Zenith Silver
I think I need to filter these two arrays by the common value in them both which is UUID and then make a new array and map on it to show data, but I am not sure how to approach in code.
This is what I have done so far
function watch() {
watches.map((watch) => {
console.log(watch.label);
});
}
watch();
function color() {
watch_colors.map((color) => {
console.log(color.label);
});
}
color();
Just loop though watches, find the matching color from watch_colors with color value in watches array is same as id value in watch_colors array. i.e, color.id === watch.color
const watches = [
{
id: "1",
label: "Rolex",
color: "UUID_OF_SILVER",
},
{
id: "2",
label: "Omega",
color: "UUID_OF_BLACK",
},
{
id: "3",
label: "Zenith",
color: "UUID_OF_SILVER",
},
];
const watch_colors = [
{
id: "UUID_OF_BLACK",
label: "Black",
},
{
id: "UUID_OF_SILVER",
label: "Silver",
},
];
watches.forEach((watch) => {
const color = watch_colors.find((color) => color.id === watch.color);
if(color) {
console.log(`${watch.label}, ${color.label}`);
}
})
You can make it more efficient using Map to make a dictionary and then loop over watches to print the result.
const watches = [
{
id: "1",
label: "Rolex",
color: "UUID_OF_SILVER",
},
{
id: "2",
label: "Omega",
color: "UUID_OF_BLACK",
},
{
id: "3",
label: "Zenith",
color: "UUID_OF_SILVER",
},
];
const watch_colors = [
{
id: "UUID_OF_BLACK",
label: "Black",
},
{
id: "UUID_OF_SILVER",
label: "Silver",
},
];
const dict = new Map();
watch_colors.forEach(({ id, label }) => dict.set(id, label));
watches.forEach((o) => console.log(`${o.label} ${dict.get(o.color)}`));
You can use the reduce method like the following:
const newWatches = watches.map((val) => {
const color = watch_colors.find((x) => x.id === val.color);
return `${val.label} ${color.label}`;
});
console.log(newWatches);
// prints [ 'Rolex Silver', 'Omega Black', 'Zenith Silver' ]

How to covert object array to Array List using for loop

Hey I am trying to convert object in array list i tried a lot of but i could not convert here is the code that i tried
const dat1 = [];
for (let i = 0; i < topology.length; i++) {
const data = [data1[i]];
dat1.push({
value:data
});
}
Here is the result that i got of value .
const topology = [
{
label: "secondary",
value: 0.10558737933770979
},
{
label: "unclassified",
value: 0.07702637029193307
},
{
label: "residential",
value: 0.05898100977978933
},
{
label: "tertiary",
value: 0.3012573789201084
},
{
label: "primary",
value: 0.44342463442819086
},
{
label: "primary_link",
value: 0.013723227242268547
},
];
and Here is the result that i want value look like in Array form.
const topology = [
{
label: "secondary",
value: [0.10558737933770979]
},
{
label: "unclassified",
value: [0.07702637029193307]
},
{
label: "residential",
value: [0.05898100977978933]
},
{
label: "tertiary",
value: [0.3012573789201084]
},
{
label: "primary",
value: [0.44342463442819086]
},
{
label: "primary_link",
value: [0.01372322724226854]
},
];
You could map the original topology and then just return the value wrapped in an array, like so:
const topology = [
{
label: "secondary",
value: 0.10558737933770979,
},
{
label: "unclassified",
value: 0.07702637029193307,
},
{
label: "residential",
value: 0.05898100977978933,
},
{
label: "tertiary",
value: 0.3012573789201084,
},
{
label: "primary",
value: 0.44342463442819086,
},
{
label: "primary_link",
value: 0.013723227242268547,
},
];
let result = topology.map(({ label, value }) => ({ label, value: [value] }));
console.log(result);
You can also follow your approach, like so:
const data1 = [];
for (let i = 0; i < topology.length; i++) {
const data = [topology[i].value];
data1.push({
label: topology[i].label,
value: data,
});
}
You were very close, just missing getting the value to be wrapped, i.e. you want the "old data", not the current new, so not [data1[i]] but [topology[i].value] and then adding the label to the new object in data1 array.
const topology = [
{
label: "secondary",
value: 0.10558737933770979,
},
{
label: "unclassified",
value: 0.07702637029193307,
},
{
label: "residential",
value: 0.05898100977978933,
},
{
label: "tertiary",
value: 0.3012573789201084,
},
{
label: "primary",
value: 0.44342463442819086,
},
{
label: "primary_link",
value: 0.013723227242268547,
},
];
const data1 = [];
for (let i = 0; i < topology.length; i++) {
const data = [topology[i].value];
data1.push({
label: topology[i].label,
value: data,
});
}
console.log(data1);
You could do something like this:
const changed = topology.map(({ label, value }) => ({
label,
value: [value]
}));
Basically just transforms the original data to wrap the value as an array with a single element.

Transform Object attribute to array of object

I want to merge Array of ObjectA containing ObjectB attribute by ObjectA attribute.
For example :
let myArray = [
{ name: 'Jeu', series: { name: 'testA', value: '89' } },
{ name: 'Dim', series: { name: 'testB', value: '490' } },
{ name: 'Dim', series: { name: 'testC', value: '978' } }
]
And I would like to transform it to
[
{ name: 'Jeu', series: { name: 'testA', value: '89' } },
{ name: 'Dim', series: [{ name: 'testB', value: '490' },{ name: 'testC', value: '978' } ] }
]
Am I able to do that with a simple reduce/map loop ?
You can first use reduce (with some spread syntax) to build an object that maps unique names and objects in the format you want to have, grouping series by name. Then, you can simply get the values from this object.
const myArray = [
{ name: 'Jeu', series: { name: 'testA', value: '89' } },
{ name: 'Dim', series: { name: 'testB', value: '490' } },
{ name: 'Dim', series: { name: 'testC', value: '978' } }
];
const map = myArray.reduce(
(acc, curr) => ({
...acc,
[curr.name]: {
name: curr.name,
series: acc[curr.name]
? [...acc[curr.name].series, curr.series]
: [curr.series]
}
}),
{}
);
const output = Object.values(map);
console.log(output);

How to use ternary operator while pushing elements into the array

I am trying to add the objects into the array based on the condition.
My expectation is to add two objects when the condition met but I am getting only the last object getting added (its element is missing).
const country = ‘USA’
citizenArray.push([
{
label: ‘Alex’,
value: ’32’,
},
country === ‘USA’
? ({
label: ‘John’,
value: ’28’,
},
{
label: ‘Miller’,
value: ’40’,
})
: {
label: ‘Marsh’,
value: ’31’,
},
]);
The output I am getting:
[{
label: ‘Alex’,
value: ’32’,
},
{
label: ‘Miller’,
value: ’40’,
}]
Expected:
[{
label: ‘Alex’,
value: ’32’,
},
{
label: ‘John’,
value: ’28’,
},
{
label: ‘Miller’,
value: ’40’,
}]
Could somebody help me point out where I am doing wrong?
Thanks.
In Javascript when you placed comma-separated expressions within parathesis it will execute each(left to right) and will return the result of last.
In your case ({ label: 'John', value: '28',}, { label: 'Miller', value: '40',}) results just the last object { label: ‘Miller’, value: ’40’, } and adds to the array.
To make it work to use an array and then use spread syntax to add them.
const country = 'USA';
const citizenArray = [];
citizenArray.push([{
label: 'Alex',
value: '32',
},
...(country === 'USA' ? [{
label: 'John',
value: '28',
}, {
label: 'Miller',
value: '40',
}] : [{
label: 'Marsh',
value: '31',
}])
]);
console.log(citizenArray);
Just use different logic like so:
const country = "USA";
let citizenArray = [];
citizenArray.push([{ label: "Alex", value: "32" }, ...(country == "USA" ? [{ label: "John", value: "28" }, { label: "Miller", value: "40" }] : [{ label: "Marsh", value: "31" }])]);
console.log(citizenArray);
.as-console-wrapper { max-height: 100% !important; top: auto; }
How about using the Spread ... operator
const myArray = [
...(condition1 ? [item1] : []),
...(condition2 ? [item2] : []),
...(condition3 ? [item3] : []),
];

Categories

Resources