Reputation: 6471
const data = [
{
id: "1",
name: "monkey",
category: {
id: "2",
color: "blue"
}
},
{
id: "2",
name: "cat",
category: {
id: "1",
color: "red"
}
},
{
id: "3",
name: "snake",
category: {
id: "2"
color: "blue",
}
},
{
id: "4",
name: "elephant",
category: {
id: "1"
color: "green"
}
}
];
This is my code:
return (data.map(obj => obj.category ? `color: ${obj.category.color} , name: ${obj.name}` : `${obj.name}`)).join('<br>');
The output is:
color: blue, name: monkey
color: red, name: cat
color: blue, name: snake
color: green, name: elephant
What I am trying to do is group the output by category would be:
color: blue, name: monkey
color: blue, name: snake
color: green, name: elephant
color: red, name: cat
This is my approach:
return (data.map(data.groupBy(obj.category, "category"),obj => obj.category ? `color: ${obj.category.color} , name: ${obj.name}` : `${obj.name}`)).join('<br>').sort();
But I get the error
obj is not defined
Upvotes: 3
Views: 64
Reputation: 386700
You could use the grouping function with a callback fo rgrouping with a function for nested properties and get the result in a flat array. Then add your style to the array for the output.
Array.prototype.groupBy = function (prop) {
return this.reduce(function (groups, item) {
const val = typeof prop === 'function' ? prop(item) : item[prop];
groups[val] = groups[val] || [];
groups[val].push(item);
return groups;
}, {})
};
const
data = [{ id: "1", name: "monkey", category: { id: "2", color: "blue" } }, { id: "2", name: "cat", category: { id: "1", color: "red" } }, { id: "3", name: "snake", category: { id: "2", color: "blue", } }, { id: "4", name: "elephant", category: { id: "1", color: "green" } }],
grouped = Object
.values(data.groupBy(o => o.category.id))
.reduce((a, b) => [...a, ...b]),
result = Object
.values(grouped)
.map(obj => `color: ${obj.category.color} , name: ${obj.name}`).join('<br>');
console.log(grouped);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 19080
You can get result
using Array.prototype.sort() and Array.prototype.map()
Also notice the use of unary plus (+) to cast the id
to numeric value
Code:
const data = [{id: "1",name: "monkey",category: {id: "2",color: "blue"}},{id: "2",name: "cat",category: {id: "1",color: "red"}},{id: "3",name: "snake",category: {id: "2",color: "blue",}},{id: "4",name: "elephant",category: {id: "1",color: "green"}}];
const result = data
.sort((a,b) => +b.category.id - +a.category.id)
.map(obj => `color: ${obj.category.color}, name: ${obj.name}`);
console.log(result);
Upvotes: 1
Reputation: 122085
You could use reduce
method to group in one object and then you can create string with map
and join
from Object.values()
.
const data = [{"id":"1","name":"monkey","category":{"id":"2","color":"blue"}},{"id":"2","name":"cat","category":{"id":"1","color":"red"}},{"id":"3","name":"snake","category":{"id":"2","color":"blue"}},{"id":"4","name":"elephant","category":{"id":"1","color":"green"}}]
const group = data.reduce((r, {name, category: {color}}) => {
const str = `color: ${color}, name: ${name}`
r[color] = (r[color] || []).concat(str)
return r;
}, {})
const res = Object.values(group)
.map(e => e.join('\n'))
.join('\n')
console.log(res)
Upvotes: 1
Reputation: 13912
Sort the data first:
data.sort((a,b) => Number(a.category.id) - Number(b.category.id));
Then do your operation for logging them all or whatever
Upvotes: 2