Search code examples
javascriptarraysecmascript-6javascript-objects

Best way of grouping array objects by multiple values in javascript.ES6


Good day developers Im wondering how I could group an array of objects of different values in specific sub-groups , where in each sub-group my contain objects with specific values according to the key queried.

My array would be something like this

const cars = 
  [ { make: 'audi', model: 'r8',      year: '2012' } 
  , { make: 'audi', model: 'rs5',     year: '2013' } 
  , { make: 'ford', model: 'mustang', year: '2012' } 
  , { make: 'ford', model: 'fusion',  year: '2015' } 
  , { make: 'kia',  model: 'optima',  year: '2012' } 
  ] 

And i would like to gather by the key make in a subgroup of name 2nd_class all objects that in the key make, had as value kia or ford, gathering the others in a group 1rst_class Having as result an object like :

const expected = 
  [ '2nd_class': 
    [ { make: 'ford', model: 'mustang', year: '2012' } 
    , { make: 'ford', model: 'fusion',  year: '2015' } 
    , { make: 'kia',  model: 'optima',  year: '2012' } 
    ] 
  , '1rst_class' : 
    [ { make: 'audi', model: 'r8',  year: '2012' } 
    , { make: 'audi', model: 'rs5', year: '2013' } 
    ] 
  ]

All the examples on the web always refer to grouping by key and one specific value .... Any help would be amazing.


Solution

  • Or you can simply do this:

    const cars = [ 
     { make: 'audi', model: 'r8',      year: '2012' }, 
     { make: 'audi', model: 'rs5',     year: '2013' }, 
     { make: 'ford', model: 'mustang', year: '2012' },
     { make: 'ford', model: 'fusion',  year: '2015' },
     { make: 'kia',  model: 'optima',  year: '2012' } 
    ];
    
    const cars_in_classes=cars.reduce((a,c)=>{
      const cls=(c.make==="audi"?"1st":"2nd")+"_class";
      (a[cls]=a[cls]||[]).push(c);
      return a;}, {} );
    
    console.log(cars_in_classes);

    The line (a[cls]=a[cls]||[]).push(c); checks whether the object property a[cls] already exists and - if not - creates it as an empty array before the current element is pushed onto it.

    In case you consider several brands to be "1st_class" you could change line 2 to this:

    const cls=(["audi","mercedes"].indexOf(c.make)>-1?"1st":"2nd")+"_class";