You codes are a little close to the goal, just need to adjust something.
Please see the comment in below demo:
When
acc.finddoesn'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)
Answer from Sphinx on Stack OverflowYou codes are a little close to the goal, just need to adjust something.
Please see the comment in below demo:
When
acc.finddoesn'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 }] });
How to reduce array of objects to array
javascript - How to reduce objects in an array based off an existing key value - Stack Overflow
javascript - reduce/filter array of objects by object key - Stack Overflow
Node.js javascript: Reduce Array of Object by Multiple Key Value - Stack Overflow
Videos
You can use reduce
const data = [{
name: 'James',
sex: 'male',
}, {
name: 'Mike',
sex: 'male',
}, {
name: 'Janet',
sex: 'female',
}, {
name: 'Mary',
sex: 'female',
}];
const result = data.reduce((c, v) => {
c[v.sex] = c[v.sex] || []; //Initiate if key does not exist
c[v.sex].push(v); //Push the value
return c;
}, {});
console.log(result);
If you want the keys to be plural, you can just append 's'
const result = data.reduce((c, v) => {
let k = v.sex + 's';
c[k] = c[k] || []; //Initiate if key does not exist
c[k].push(v); //Push the value
return c;
}, {});
Something simple with plain old js -
const data = [{
name: 'James',
sex: 'male',
}, {
name: 'Mike',
sex: 'male',
}, {
name: 'Janet',
sex: 'female',
}, {
name: 'Mary',
sex: 'female',
}];
var result = { males: [], females: []};
data.forEach(function(person){
person.sex === 'male' ? result.males.push(person) : result.females.push(person);
});
console.log(result);
If you are ok with using lodash, try groupBy
const data = [
{ start: "10-05-2018", assigned_agent: "1257434" },
{ start: "10-05-2018", assigned_agent: "1257434" },
{ start: "10-05-2018", assigned_agent: "1257434" },
{ start: "10-06-2018", assigned_agent: "1257434" },
{ start: "10-05-2018", assigned_agent: "1277852" },
{ start: "10-05-2018", assigned_agent: "1277852" },
]
const group_by_both = _.chain(data)
.groupBy((el) => `${el.start} ${el.assigned_agent}`)
.values()
.value()
console.log(group_by_both)
.as-console-wrapper { max-height: 100% !important; }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
var data = [{
start: '10-05-2018',
assigned_agent: '1257434'
},
{
start: '10-05-2018',
assigned_agent: '1257434'
},
{
start: '10-05-2018',
assigned_agent: '1257434'
},
{
start: '10-06-2018',
assigned_agent: '1257434'
},
{
start: '10-05-2018',
assigned_agent: '1277852'
},
{
start: '10-05-2018',
assigned_agent: '1277852'
}
];
var grouped = data.reduce((accumulator, element) => {
// group by start and agent, so combine values for unique key
var key = element.start + element.assigned_agent;
// if there is not already a grouping, make an empty array
accumulator[key] = accumulator[key] || [];
// add the element to the desired group
accumulator[key].push(element);
// return the accumulator for the next iteration
return accumulator;
}, {});
console.log(grouped);
One option would be to reduce the keys():
var o = {
a: {value:1},
b: {value:2},
c: {value:3}
};
Object.keys(o).reduce(function (previous, key) {
return previous + o[key].value;
}, 0);
With this, you'll want to specify an initial value or the 1st round will be 'a' + 2.
If you want the result as an Object ({ value: ... }), you'll have to initialize and return the object each time:
Object.keys(o).reduce(function (previous, key) {
previous.value += o[key].value;
return previous;
}, { value: 0 });
What you actually want in this case are the Object.values. Here is a concise ES6 implementation with that in mind:
const add = {
a: {value:1},
b: {value:2},
c: {value:3}
}
const total = Object.values(add).reduce((t, {value}) => t + value, 0)
console.log(total) // 6
or simply:
const add = {
a: 1,
b: 2,
c: 3
}
const total = Object.values(add).reduce((t, n) => t + n)
console.log(total) // 6