简体   繁体   English

通过多个键对对象数组进行分组

[英]Grouping array of objects by multiple keys

I feel embarrassed for asking this question as I should know how to figure it out, but I'm spinning my wheels on grouping an array of objects by multiple keys.问这个问题我感到很尴尬,因为我应该知道如何解决这个问题,但我正在旋转我的轮子,通过多个键对一组对象进行分组。

Here's the 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"
      },
]

What I've been trying to generate with little success is the following:我一直在尝试生成但收效甚微的内容如下:

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

The schema is:架构是:

{
    "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"]
        }
    }]
}

I've tried the following with lodash我用 lodash 尝试了以下方法

  let result = _.chain(carData)
    .groupBy('car')
    .toPairs()
    .map(function(curr) {
        return _.zipObject(['car', 'year'], curr);
    })
    .value();

This gets me part of the way , but I end up with incomplete data when it comes to the styles and types for each year of the car. 这让我了解了一部分,但当涉及到每年汽车的样式和类型时,我最终得到的数据不完整。

You could use a hash object and a nested approach for the given properties.您可以对给定的属性使用散列对象和嵌套方法。

 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; }

Here's a (slightly verbose) solution that generates exactly the JSON object shape you wanted and groups by unlimited keys:这是一个(略显冗长)的解决方案,可以准确生成您想要的 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']));

Here's a running example: http://codepen.io/rarmatei/pen/evmBOo这是一个运行示例: http ://codepen.io/rarmatei/pen/evmBOo

 const groupBy = function groupBy(list, properties, propertyIndex) { // current property index let i = propertyIndex === undefined ? 0 : propertyIndex; // group by let grouppedObj = list.reduce((acc, obj) => { let groupedValue = obj[properties[i]]; if (!groupedValue) { return acc; } if (!acc[groupedValue]) { acc[groupedValue] = []; } acc[groupedValue].push({ ...obj, groupBy: properties.join(",") }); return acc; }, {}); // group by nested const keys = Object.keys(grouppedObj); if (i === properties.length - 1) { return grouppedObj; } keys.forEach((key) => { grouppedObj[key] = groupBy(grouppedObj[key], properties, i + 1); }); return grouppedObj; }; const data =[ { "year": "2021", "cabin": "1", "months": ["1", "2"] }, { "year": "2021", "cabin": "1", "months": ["4"] }, { "year": "2021", "cabin": "2", "months": ["1", "2"] }, { "year": "2022", "cabin": "1", "months": ["1", "2"] }, { "year": "2022", "cabin": "1", "months": ["4"] }, { "year": "2022", "cabin": "2", "months": ["1", "2"] } ]; const results=groupBy(data, ["year", "cabin"]); console.log(results);

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

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