从JS中的对象列表中收集索引统计信息

时间:2019-06-25 12:04:39

标签: javascript json

所以我有一个对象列表,例如。

viewDidLoad

(请注意,对象也具有其他属性)

我正在寻找结果提取出来的一些压缩细节:

var data = [{a: 'data1', b: 'subdata1'}, {a: 'data2', b: 'subdata2'}, {a: 'data1', b: 'subdata3'}, {a: 'data1', b: 'subdata1'}]

我已经可以用reduce来计算类型(或子类型):

[{type: 'data1', list: [{subtype: 'subdata1', count: 2}, {subtype: 'subdata3', count: 1}]}, {type: 'data2', list: [{subtype: 'data2', count: 1}]}]

但是,这不完全是我要实现的结构或完整细节。我显然可以使用for循环手动完成工作,但我希望更好地理解map,reduce等,以实现更简洁的实现。

1 个答案:

答案 0 :(得分:2)

您可以创建一个嵌套的查找表(a-> b->计数),然后可以对其进行迭代并生成结果:

  const table = {};

  for(const { a, b } of data) {
    if(!table[a]) table[a] = {};
    if(!table[a][b]) table[a][b] = 0;
    table[a][b]++;
  }

  const result = Object.entries(table)
     .map(([type, entries]) => ({ type, list: Object.entries(entries).map(([ subtype, count ]) => ({ subtype, count })), }));

是的,一个可以将其写为功能链:

   const result = Object.entries(
     data.reduce(
        ((table, { a, b }) => (table[a] || (table[a] = {}))[b] = (table[a][b] || 0) + 1, table),
        {}
     )
   ).map(([type, entries]) =>  ({
      type, 
      list: Object.entries(entries).map(([ subtype, count ]) => ({ subtype, count })),
   }));

但是IMO的可读性较差。