按多个键分组对象数组

时间:2017-02-24 21:47:55

标签: javascript arrays sorting group-by

我因为问这个问题而感到尴尬,因为我应该知道如何解决这个问题,但是我在通过多个键对一组对象进行分组时旋转我的轮子。

这是数据:

[
      {
        "car": "audi",
        "type": "A6",
        "style": "Avant",
        "year": "1996"
      },
      {

        "car": "audi",
        "type": "A4",
        "style": "2",
        "year": "2006"
      },
      {

        "car": "audi",
        "type": "A4",
        "style": "L W12",
        "year": "2006"
      },
      {

        "car": "audi",
        "type": "80",
        "style": "GLE",
        "year": "1975"
      },
      {

        "car": "audi",
        "type": "A6",
        "style": "Avant L",
        "year": "1996"
      },
      {
        "car": "audi",
        "type": "A6",
        "style": "3.2 Multitronic",
        "year": "2006"
      },
]

我一直在努力取得的成就如下:

 [{
   "audi": [{
     "1996": {
       "A6": ["Avant, Avant L"]
     }
   }, {
     "2006": }
       "A6": ["3.2 Multitronic"],
       "A4": ["L W12", "2"]
     }
   }
   ....
 }]

架构是:

{
    "car1": [{
        "year1": {
            "style1": ["trim1", "trim2"],
            "style2": ["trim1", "trim2"]
        },
        "year1": {
            "style1": ["trim1", "trim2"],
            "style2": ["trim1", "trim2"]
        }
    }],
    "car2": [{
        "year1": {
            "style1": ["trim1", "trim2"],
            "style2": ["trim1", "trim2"]
        },
        "year2": {
            "style1": ["trim1", "trim2"],
            "style2": ["trim1", "trim2"]
        }
    }]
}

我已经用lodash

尝试了以下内容
  let result = _.chain(carData)
    .groupBy('car')
    .toPairs()
    .map(function(curr) {
        return _.zipObject(['car', 'year'], curr);
    })
    .value();

This gets me part of the way,但是当涉及到汽车每年的款式和类型时,我最终会得到不完整的数据。

2 个答案:

答案 0 :(得分:1)

您可以为给定的属性使用哈希对象和嵌套方法。

var data = [{ car: "audi", type: "A6", style: "Avant", year: 1996 }, { car: "audi", type: "A4", style: 2, year: 2006 }, { car: "audi", type: "A4", style: "L W12", year: 2006 }, { car: "audi", type: 80, style: "GLE", year: 1975 }, { car: "audi", type: "A6", style: "Avant L", year: 1996 }, { car: "audi", type: "A6", style: "3.2 Multitronic", year: 2006 }],
    keys = ['car', 'year', 'type'],
    result = [];

data.forEach(function (a) {
    keys.reduce(function (r, k) {
        var o = {};
        if (!r[a[k]]) {
            r[a[k]] = { _: [] };
            o[a[k]] = r[a[k]]._;
            r._.push(o);
        }
        return r[a[k]];
    }, this)._.push(a.style);
}, { _: result });
   
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)

这是一个(稍微详细)的解决方案,可以生成您想要的JSON对象形状和无限制键组:



var cars = [{
  "car": "audi",
  "type": "A6",
  "style": "Avant",
  "year": "1996"
}, {

  "car": "audi",
  "type": "A4",
  "style": "2",
  "year": "2006"
}, {

  "car": "audi",
  "type": "A4",
  "style": "L W12",
  "year": "2006"
}, {

  "car": "audi",
  "type": "80",
  "style": "GLE",
  "year": "1975"
}, {

  "car": "audi",
  "type": "A6",
  "style": "Avant L",
  "year": "1996"
}, {
  "car": "audi",
  "type": "A6",
  "style": "3.2 Multitronic",
  "year": "2006"
}, ];

function groupBy(list, prop) {
  return list.reduce((groupped, item) => {
    var key = item[prop];
    delete item[prop];
    if (groupped.hasOwnProperty(key)) {
      groupped[key].push(item);
    } else {
      groupped[key] = [item];
    }
    return groupped
  }, {});
}

function groupSubKeys(obj, properties, propIndex) {
  var grouppedObj = groupBy(obj, properties[propIndex]);
  Object.keys(grouppedObj).forEach((key) => {
    if (propIndex < properties.length - 2) {
      grouppedObj[key] = groupSubKeys(grouppedObj[key], properties, propIndex + 1);
    } else {
      grouppedObj[key] = grouppedObj[key].map(item => item[properties[propIndex + 1]])
    }
  });
  return grouppedObj;
}

function groupByProperties(list, properties) {
  return groupSubKeys(list, properties, 0);
}

console.log(groupByProperties(cars, ['car', 'year', 'type', 'style']));
&#13;
&#13;
&#13;

这是一个正在运行的例子: http://codepen.io/rarmatei/pen/evmBOo

相关问题