canmustu
canmustu

Reputation: 2649

Is there a way to groupBy data by multiple field by lodash in Javascript

I want to groupBy my data by multiple fields. So, I added the data and expected result.

const skus = [
  {
    id: 1,
    customAttributes: {
      Color: 'Red',
      Size: 'S',
      Season: 2019
    }
  },
  {
    id: 2,
    customAttributes: {
      Color: 'Red',
      Size: 'S',
      Season: 2020
    }
  },
  {
    id: 3,
    customAttributes: {
      Color: 'Red',
      Size: 'M',
      Season: 2019
    }
  },
  {
    id: 4,
    customAttributes: {
      Color: 'Red',
      Size: 'M',
      Season: 2020
    }
  },
  {
    id: 5,
    customAttributes: {
      Color: 'Red',
      Size: 'L',
      Season: 2019
    }
  },
  {
    id: 6,
    customAttributes: {
      Color: 'Red',
      Size: 'L',
      Season: 2020
    }
  },
  {
    id: 7,
    customAttributes: {
      Color: 'Green',
      Size: 'S',
      Season: 2019
    }
  },
  {
    id: 8,
    customAttributes: {
      Color: 'Green',
      Size: 'S',
      Season: 2020
    }
  },
  {
    id: 9,
    customAttributes: {
      Color: 'Green',
      Size: 'M',
      Season: 2019
    }
  },
  {
    id: 10,
    customAttributes: {
      Color: 'Green',
      Size: 'M',
      Season: 2020
    }
  },
  {
    id: 11,
    customAttributes: {
      Color: 'Green',
      Size: 'L',
      Season: 2019
    }
  },
  {
    id: 12,
    customAttributes: {
      Color: 'Green',
      Size: 'L',
      Season: 2020
    }
  }
];

console.log( // groupBy is working by 1 parameter, but I don't know to make it multiple parameter
  _.chain(skus)
    .map(sku => sku.customAttributes)
    .groupBy('Color')
    .map((value, key) => ({ title: key, skus: value }))
    .value()
);

// Just like: groupBy('Color', 'Size')

I want to groupBy these skus by multiple parameters just like Color and Size by using lodash.

By 1 parameter, it is working well. But when multiple parameters, I can not make it right.

The expected result is:

[
    {
        title: 'Red / S', // Color / Size
        skus: [
            {
                id: 1,
                customAttributes: {
                  Color: 'Red',
                  Size: 'S',
                  Season: 2019
                }
            },
            {
                id: 2,
                customAttributes: {
                  Color: 'Red',
                  Size: 'S',
                  Season: 2020
                }
            }
        ]
    },
    {
        title: 'Red / M', // Color / Size
        skus: [
            {
                id: 3,
                customAttributes: {
                  Color: 'Red',
                  Size: 'M',
                  Season: 2019
                }
            },
            {
                id: 4,
                customAttributes: {
                  Color: 'Red',
                  Size: 'M',
                  Season: 2020
                }
            }
        ]
    },
    ....
]

Thank you.

Upvotes: 0

Views: 67

Answers (1)

Ori Drori
Ori Drori

Reputation: 192287

Remove the map to customAttributes, since it you want the object with the id in the result. Pass a function to _.groupBy(), and return a string that includes the fields you want to use as the groups' keys.

const skus = [{"id":1,"customAttributes":{"Color":"Red","Size":"S","Season":2019}},{"id":2,"customAttributes":{"Color":"Red","Size":"S","Season":2020}},{"id":3,"customAttributes":{"Color":"Red","Size":"M","Season":2019}},{"id":4,"customAttributes":{"Color":"Red","Size":"M","Season":2020}},{"id":5,"customAttributes":{"Color":"Red","Size":"L","Season":2019}},{"id":6,"customAttributes":{"Color":"Red","Size":"L","Season":2020}},{"id":7,"customAttributes":{"Color":"Green","Size":"S","Season":2019}},{"id":8,"customAttributes":{"Color":"Green","Size":"S","Season":2020}},{"id":9,"customAttributes":{"Color":"Green","Size":"M","Season":2019}},{"id":10,"customAttributes":{"Color":"Green","Size":"M","Season":2020}},{"id":11,"customAttributes":{"Color":"Green","Size":"L","Season":2019}},{"id":12,"customAttributes":{"Color":"Green","Size":"L","Season":2020}}];

const result = _(skus)
  .groupBy(({ customAttributes: a }) => `${a.Color} / ${a.Size}`)
  .map((skus, title) => ({ title, skus }))
  .value();
  
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Upvotes: 1

Related Questions