In my nodeJs code I am fetching some records from database. I am getting the data as JSON as below:
"Data": [{
"id": 1,
"color": "blue",
"model_name": "ford",
"year": 2016
}, {
"id": 2,
"color": "blue",
"model_name": "Maruti",
"year": 2016
}, {
"id": 3,
"color": "red",
"model_name": "Fiat",
"year": 2016
}, {
"id": 4,
"color": "red",
"model_name": "tata",
"year": 2016
}]
What I want is something like the following JSON:
"Data": [{
"color": "blue",
car: [{
"id": 1,
"color": "blue",
"model_name": "ford",
"year": 2016
}, {
"id": 2,
"color": "blue",
"model_name": "Maruti",
"year": 2016
}]
}, {
"color": "red",
car: [{
"id": 3,
"color": "red",
"model_name": "Fiat",
"year": 2016
}, {
"id": 4,
"color": "red",
"model_name": "tata",
"year": 2016
}]
}]
I could have achieved this using 'groupBy' method of underscore JS by using the code below:
var groupedData = _.groupBy(rows, f=>{return f.color});
However the output becomes:
"Data": [{
"blue": [{
"id": 1,
"color": "blue",
"model_name": "ford",
"year": 2016
}, {
"id": 2,
"color": "blue",
"model_name": "Maruti",
"year": 2016
}]
}, {
"red": [{
"id": 3,
"color": "red",
"model_name": "Fiat",
"year": 2016
}, {
"id": 4,
"color": "red",
"model_name": "tata",
"year": 2016
}]
}]
Here the problem is that the color name is itself the key. I want to have "color": "blue" , in this format but in a group by way.
In my nodeJs code I am fetching some records from database. I am getting the data as JSON as below:
"Data": [{
"id": 1,
"color": "blue",
"model_name": "ford",
"year": 2016
}, {
"id": 2,
"color": "blue",
"model_name": "Maruti",
"year": 2016
}, {
"id": 3,
"color": "red",
"model_name": "Fiat",
"year": 2016
}, {
"id": 4,
"color": "red",
"model_name": "tata",
"year": 2016
}]
What I want is something like the following JSON:
"Data": [{
"color": "blue",
car: [{
"id": 1,
"color": "blue",
"model_name": "ford",
"year": 2016
}, {
"id": 2,
"color": "blue",
"model_name": "Maruti",
"year": 2016
}]
}, {
"color": "red",
car: [{
"id": 3,
"color": "red",
"model_name": "Fiat",
"year": 2016
}, {
"id": 4,
"color": "red",
"model_name": "tata",
"year": 2016
}]
}]
I could have achieved this using 'groupBy' method of underscore JS by using the code below:
var groupedData = _.groupBy(rows, f=>{return f.color});
However the output becomes:
"Data": [{
"blue": [{
"id": 1,
"color": "blue",
"model_name": "ford",
"year": 2016
}, {
"id": 2,
"color": "blue",
"model_name": "Maruti",
"year": 2016
}]
}, {
"red": [{
"id": 3,
"color": "red",
"model_name": "Fiat",
"year": 2016
}, {
"id": 4,
"color": "red",
"model_name": "tata",
"year": 2016
}]
}]
Here the problem is that the color name is itself the key. I want to have "color": "blue" , in this format but in a group by way.
Share Improve this question edited Sep 27, 2016 at 13:08 Mr. Polywhirl 48.6k12 gold badges93 silver badges144 bronze badges asked Sep 27, 2016 at 12:47 aroz2016aroz2016 231 gold badge1 silver badge5 bronze badges 1 |4 Answers
Reset to default 9One other straightforward way of this by pure ES6 code.
var data = [
{
"id": 1,
"color": "blue",
"model_name": "ford",
"year": 2016
},
{
"id": 2,
"color": "blue",
"model_name": "Maruti",
"year": 2016
},
{
"id": 3,
"color": "red",
"model_name": "Fiat",
"year": 2016
},
{
"id": 4,
"color": "red",
"model_name": "tata",
"year": 2016
}],
hash = data.reduce((p,c) => (p[c.color] ? p[c.color].push(c) : p[c.color] = [c],p) ,{}),
newData = Object.keys(hash).map(k => ({color: k, car: hash[k]}));
console.log(newData);
Here is a short answer using lodash:
_(Data)
.groupBy((elem) => elem.color)
.map((vals, key) => ({color: key, car: vals}))
.value()
If you find that confusing, you can see it as:
_.map(
_.groupBy(Data, elem => elem.color),
(vals, key) => {
return {color: key, car: vals}
}
)
Hope this helps.
Here, I made a little groupBy
function that works in your case. In order to keep it general-purpose, I replaced the "car" key name by "items" :
function groupBy(key, array) {
var result = [];
for (var i = 0; i < array.length; i++) {
var added = false;
for (var j = 0; j < result.length; j++) {
if (result[j][key] == array[i][key]) {
result[j].items.push(array[i]);
added = true;
break;
}
}
if (!added) {
var entry = {items: []};
entry[key] = array[i][key];
entry.items.push(array[i]);
result.push(entry);
}
}
return result;
}
Now if
var data = [{
"id": 1,
"color": "blue",
"model_name": "ford",
"year": 2016
}, {
"id": 2,
"color": "blue",
"model_name": "Maruti",
"year": 2016
}, {
"id": 3,
"color": "red",
"model_name": "Fiat",
"year": 2016
}, {
"id": 4,
"color": "red",
"model_name": "tata",
"year": 2016
}]
Then
groupBy("color", data);
Should give you expected results:
[
{
"color": "blue",
"items": [
{
"id": 1,
"color": "blue",
"model_name": "ford",
"year": 2016
},
{
"id": 2,
"color": "blue",
"model_name": "Maruti",
"year": 2016
}
]
},
{
"color": "red",
"items": [
{
"id": 3,
"color": "red",
"model_name": "Fiat",
"year": 2016
},
{
"id": 4,
"color": "red",
"model_name": "tata",
"year": 2016
}
]
}
]
const data = [
{
"id": 1,
"color": "blue",
"model_name": "ford",
"year": 2016
},
{
"id": 2,
"color": "blue",
"model_name": "Maruti",
"year": 2016
},
{
"id": 3,
"color": "red",
"model_name": "Fiat",
"year": 2016
},
{
"id": 4,
"color": "red",
"model_name": "tata",
"year": 2016
}
];
const sorted = data.reduce((result, car) => {
const a = result.find(({color}) => color === car.color);
a ? a.car.push(car) : result.push({color: car.color, car: [car]});
return result;
}, []);
console.log(sorted);
Data[0].car
in your second "JSON" example. – Mr. Polywhirl Commented Sep 27, 2016 at 13:09