I have such array of objects:
[{id: 1, name: 'Apple', category: 'Fruit'}
{id: 2, name: 'Melon', category: 'Fruit'}
{id: 3, name: 'iPhone', category: 'Phone'}
{id: 4, name: 'Samsung Galaxy Note 8', category: 'Phone'}
{id: 5, name: 'Playstation 5', category: 'Entertainment'}]
and what I wanted to achieve is to combine product names by category and show them like:
Fruit
Apple
Melon
Phone
iPhone
Samsung Galaxy Note 8
Entertainment
Playstation 5
So, what I tried to achieve that is
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
const products = [{id: 1, name: 'Apple', category: 'Fruit'}
{id: 2, name: 'Melon', category: 'Fruit'}
{id: 3, name: 'iPhone', category: 'Phone'}
{id: 4, name: 'Samsung Galaxy Note 8', category: 'Phone'}
{id: 5, name: 'Playstation 5', category: 'Entertainment'}]
console.log(groupBy([products], 'category'));
CodePudding user response:
You have to adjust your reduce a bit:
const mapping = arr.reduce((obj, entry) => {
obj[entry.category] = obj[entry.category] ? [...obj[entry.category], entry] : [entry]
return obj;
}, {})
resulting in
{
Entertainment: [{
category: "Entertainment",
id: 5,
name: "Playstation 5"
}],
Fruit: [{
category: "Fruit",
id: 1,
name: "Apple"
}, {
category: "Fruit",
id: 2,
name: "Melon"
}],
Phone: [{
category: "Phone",
id: 3,
name: "iPhone"
}, {
category: "Phone",
id: 4,
name: "Samsung Galaxy Note 8"
}]
}
And you can adjust what you want to save by changing entry to a desired value of entry.
CodePudding user response:
I would approach your groupBy
method like this:
function groupBy(data, key, value) {
const groups = {};
data.forEach(element => {
let subkey = element[key];
if (!(subkey in groups)) {
groups[subkey] = [element[value]];
} else {
groups[subkey].push(element[value]);
}
});
return groups;
}
console.log(groupBy(products, "category", "name")
You loop over every element, and if the specified key is not already in the groups object it will be added. if it's already added we just add the new element to the array.
This is an example return value of the groupBy function:
{
Fruit: [ 'Apple', 'Melon' ],
Phone: [ 'iPhone', 'Samsung Galaxy Note 8' ],
Entertainment: [ 'Playstation 5' ]
}
CodePudding user response:
var groupBy = function (xs, key) {
return xs.reduce(function (rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
const arrayData = [
{ id: 1, name: 'Apple', category: 'Fruit' },
{ id: 2, name: 'Melon', category: 'Fruit' },
{ id: 3, name: 'iPhone', category: 'Phone' },
{ id: 4, name: 'Samsung Galaxy Note 8', category: 'Phone' },
{ id: 5, name: 'Playstation 5', category: 'Entertainment' }
]
console.log(groupBy(arrayData, 'category'));
result:
{
"Fruit": [
{
"id": 1,
"name": "Apple",
"category": "Fruit"
},
{
"id": 2,
"name": "Melon",
"category": "Fruit"
}
],
"Phone": [
{
"id": 3,
"name": "iPhone",
"category": "Phone"
},
{
"id": 4,
"name": "Samsung Galaxy Note 8",
"category": "Phone"
}
],
"Entertainment": [
{
"id": 5,
"name": "Playstation 5",
"category": "Entertainment"
}
]
}
CodePudding user response:
To generate HTML code
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
const products = [{id: 1, name: 'Apple', category: 'Fruit'},
{id: 2, name: 'Melon', category: 'Fruit'},
{id: 3, name: 'iPhone', category: 'Phone'},
{id: 4, name: 'Samsung Galaxy Note 8', category: 'Phone'},
{id: 5, name: 'Playstation 5', category: 'Entertainment'}];
const groups = groupBy(products, 'category');
const html = Object.keys(groups).reduce((code, cat) => {
const inner = groups[cat].reduce((i, product) => {
return i `<p>${product.name}</p>`;
}, '');
return code `<div><h2>${cat}</h2>${inner}</div>`;
}, '');
document.getElementById('container').innerHTML = html;
p { margin-left: 20px; }
<div id="container"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>