繁体   English   中英

如何使用Lodash在特定字段上的JavaScript对象数组进行分组?

[英]How to group an array of objects in JavaScript on specific fields using Lodash?

编辑:我认为这是一个比简单的_.groupBy不同的问题,因为我试图按所有键进行分组并返回哈希图而不是数组。


我有以下对象的数组:

items = [
  { created_at: "01/01/2016", name: "bob", age: 21, height: 60 },
  { created_at: "01/02/2016", age: 22, height: 70 },
  { created_at: "01/03/2016", name: "alice", age: 23 }
]

我正在尝试将其转换为以下格式:

{
  "name": [
    {
      "value": "bob",
      "created_at": "01/01/2016"
    },
    {
      "value": "alice",
      "created_at": "01/03/2016"
    }
  ],
  "age": [
    {
      "value": 21,
      "created_at": "01/01/2016"
    },
    {
      "value": 22,
      "created_at": "01/02/2016"
    },
    {
      "value": 23,
      "created_at": "01/03/2016"
    }
  ],
  "height": [
    {
      "value": 60,
      "created_at": "01/01/2016"
    },
    {
      "value": 70,
      "created_at": "01/02/2016"
    }
  ]
}

我的要求是我忽略了created_at字段,但将其他所有内容分组。

一种解决方案是:

 var items = [ { created_at: "01/01/2016", name: "bob", age: 21, height: 60 }, { created_at: "01/02/2016", age: 22, height: 70 }, { created_at: "01/03/2016", name: "alice", age: 23 } ] var store = {} for(var i=0; i < items.length; i++) { var item = items[i] for(key in item) { if(key === "created_at") { continue } value = item[key] if(!store[key]) { store[key] = [] } store[key].push({ value: value, created_at: item.created_at }) } } $('pre').text(JSON.stringify(store, null, 2)) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body><pre></pre></body> 

我想知道是否有一些很酷的方法可以在lodash使用它……也许使用.map().groupBy()东西? 我不太了解如何正确使用它们,而是试图学习新的,更优雅的代码编写方法。

使用reduce可能是最短的方法。

var baseKey = 'created_at';

var result = items.reduce(function(col, item) {
  Object.keys(item).forEach(function(key) {
    if (key === baseKey || !item[key]) return;
    var o = { value: item[key] };
    o[baseKey] = item[baseKey];
    (col[key] = col[key] || []).push(o);
  });
  return col;
}, {});

JSFiddle演示: https ://jsfiddle.net/pLcv1am2/6/

您是专门询问lodash的,所以此答案是使用lodash构造的。

注意我正在使用_.chain方法-这使链接多个操作而不是分别单独运行它们很方便。

一种非常接近(不完美)的方式(我敢肯定还有很多其他方式)是这样的:

items = _.chain(items)
  .map(function(n) {
    var created = _.get(n, 'created_at');
    var arr = [];
    _.each(n, function(n, k) {
      if (k != 'created_at') {
        arr.push({
          'field': k,
          'value': n,
          'created_at': created
        });
      }
    });
    return arr;
  })
  .flatten()
  .groupBy('field')
  .value();

结果是一个看起来像这样的集合:

{ "name": 
    [ 
        { "field": "name", "value": "bob", "created_at": "01/01/2016" }, 
        { "field": "name", "value": "alice", "created_at": "01/03/2016" } 
    ], 
  "age": [
     ....

这是一个玩弄此代码的小提琴

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM