Search code examples
javascriptlodashreduce

JS: Group by 2 keys


I have like to group an array of objects.

var _ = require('lodash')

const objects = [
  { a: 'test1', b: 'sample', c: 'ten' },
  { a: 'test2', b: 'sample', c: 'ten' },
  { a: 'test3', b: 'sampleone', c: 'ten' },
  { a: 'test4', b: 'sample', c: 'tentwo' },
]

//using lodash, groupBy b and c and concat 'a' values
const grouped = _(objects)
  .groupBy('b', 'c')
  .map((value, key) => ({
    b: key,
    c: value[0].c,
    a: _.map(value, 'a').join('|'),
  }))
  .value()

console.log(grouped)

The output from above is:

[
  { b: 'sample', c: 'ten', a: 'test1|test2|test4' },
  { b: 'sampleone', c: 'ten', a: 'test3' }
]

But I have like the output to be below, only group by b is 'sample' and c is 'ten'

[
  { b: 'sample', c: 'ten', a: 'test1|test2' },
  { b: 'sampleone', c: 'ten', a: 'test3' },
  { b: 'sample', c: 'tentwo', a: 'test4' }
]

Any help would be greatly appreciated.


Solution

  • To group by multiple keys you will to need do something like

    .groupBy(({b,c}) => `${b}|${c}`)
    

    i.e joining the individual keys and creating a new composite key (also will have create it in such a way that it becomes unique)

    now the grouped object will look like this before the map call

    {
      sampleone|ten: [{
      a: "test3",
      b: "sampleone",
      c: "ten"
    }],
      sample|ten: [{
      a: "test1",
      b: "sample",
      c: "ten"
    }, {
      a: "test2",
      b: "sample",
      c: "ten"
    }],
      sample|tentwo: [{
      a: "test4",
      b: "sample",
      c: "tentwo"
    }]
    }
    

    const objects = [
      { a: 'test1', b: 'sample', c: 'ten' },
      { a: 'test2', b: 'sample', c: 'ten' },
      { a: 'test3', b: 'sampleone', c: 'ten' },
      { a: 'test4', b: 'sample', c: 'tentwo' },
    ]
    
    
    const grouped = _(objects)
      .groupBy(({b,c}) => `${b}|${c}`)
      .map((value, key) => ({
        b: value[0].b,
        c: value[0].c,
        a: _.map(value, 'a').join('|'),
      }))
      .value()
    
    console.log(grouped)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>