最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Group by JSON data in Node - Stack Overflow

programmeradmin1浏览0评论

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
  • None of that is standard JSON. It will fail to validate. Also, you have an un-quoted key for Data[0].car in your second "JSON" example. – Mr. Polywhirl Commented Sep 27, 2016 at 13:09
Add a comment  | 

4 Answers 4

Reset to default 9

One 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);
发布评论

评论列表(0)

  1. 暂无评论