Working with an array of objects like:
const arr = [
{name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
{name: "survey with select", value: "survey with select answer", count: 2},
{name: "werasd", value: "Donald", count: 1},
{name: "werasd", value: "Jim", count: 1}
];
I am trying to reduce the array on matching values for the name
key and achieve an desired output like:
desiredOutput = [
{name: "qewregf dqewafs", data: [{value: "qewregf dqewafs answer", count: 2}]},
{name: "survey with select", data: [{value: "survey with select answer", count: 2}]},
{name: "werasd", data: [{value: "Donald", count: 1}, {value: "Jim", count: 1}]}
]
This attempt reduces the array, but I am missing how to merge the nested values without overwriting.
const arr = [{"name":"qewregf dqewafs","value":"qewregf dqewafs answer","count":2},{"name":"survey with select","value":"survey with select answer","count":2},{"name":"werasd","value":"Donald","count":1},{"name":"werasd","value":"Jim","count":1}];
const result = arr.reduce((acc, d) => {
const found = acc.find(a => a.name === d.name);
const value = { name: d.name, val: d.value };
if (found) {
acc.push(...value);
}
else {
acc.push({ name: d.name, data: [{ value: d.value }, { count: d.count }] });
}
return acc;
}, []);
console.log(result);
What am I missing?
Array. filter() removes all duplicate objects by checking if the previously mapped id-array includes the current id ( {id} destructs the object into only its id).
We can remove duplicate element in an array by 2 ways: using temporary array or using separate index. To remove the duplicate element from array, the array must be in sorted order. If array is not sorted, you can sort it by calling Arrays. sort(arr) method.
Answer: Use the indexOf() Method You can use the indexOf() method in conjugation with the push() remove the duplicate values from an array or get all unique values from an array in JavaScript.
No, JavaScript objects cannot have duplicate keys. The keys must all be unique.
You codes are a little close to the goal, just need to adjust something.
Please see the comment in below demo:
When acc.find
doesn't find anything, then push one element {name:d.name, data: [value]}
if found, then push one {value: ...}
into data property.
const arr = [
{name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
{name: "survey with select", value: "survey with select answer", count: 2},
{name: "werasd", value: "Donald", count: 1},
{name: "werasd", value: "Jim", count: 1}
];
const result = arr.reduce((acc, d) => {
const found = acc.find(a => a.name === d.name);
//const value = { name: d.name, val: d.value };
const value = { value: d.value, count: d.count }; // the element in data property
if (!found) {
//acc.push(...value);
acc.push({name:d.name, data: [value]}) // not found, so need to add data property
}
else {
//acc.push({ name: d.name, data: [{ value: d.value }, { count: d.count }] });
found.data.push(value) // if found, that means data property exists, so just push new element to found.data.
}
return acc;
}, []);
console.log(result)
You're not far off. This would be a simple change to two lines of your code to achieve it:
const arr = [
{name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
{name: "survey with select", value: "survey with select answer", count: 2},
{name: "werasd", value: "Donald", count: 1},
{name: "werasd", value: "Jim", count: 1}
];
const result = arr.reduce((acc, d) => {
const found = acc.find(a => a.name === d.name);
const value = { name: d.name, val: d.value };
if (found) {
found.data.push(value);
}
else {
acc.push({ name: d.name, data: [{ value: d.value, count: d.count }] });
}
return acc;
}, []);
console.log(result)
Here are the differences:
- acc.push(...value);
+ found.data.push(value);
- acc.push({ name: d.name, data: [{ value: d.value }, { count: d.count }] });
+ acc.push({ name: d.name, data: [{ value: d.value, count: d.count }] });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With