Skip to content
Advertisement

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

  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.

Advertisement

Answer

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; }
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement