0

I have an array like this (1st level nesting is intended)

const names = [
    [{
        name: "John",
        country: "USA"
    }, {
        name: "Mary",
        country: "UK"
    }], {
        name: "Paul",
        country: "USA"
    }
]

I would like to convert this into

const groupBy = [{
        country: "USA",
        names: [{
            name: "John"
        }, {
            name: "Paul"
        }]
    },
    {
        country: "UK",
        names: [{
            name: "Mary"
        }]
    }
]

I am wondering how I could use reduce() or another method to achieve the desired outcomes?

Krupesh Kotecha
  • 2,396
  • 3
  • 21
  • 40
neo-technoker
  • 369
  • 2
  • 8
  • 26

1 Answers1

1

You could use lodash flatten to remove nesting, but I handle the nesting by calling reduce again. Lodash also has a groupBy but that gives you a keyed object, which is not what you want. So here is a non-lib based solution, it supports infinite nesting of arrays.

    const names = [[{
        name: "John",
        country: "USA"
    }, {
        name: "Mary",
        country: "UK"
    }], {
        name: "Paul",
        country: "USA"
    }];

    const reducer = (groupBy, el) => {

        if (Array.isArray(el)) {
            return el.reduce(reducer, groupBy);
        } else {
            const { country, ...rest } = el;
            const group = groupBy.find(el => el.country === country);
            if (group) {
                group.names.push(rest);
            } else {
                groupBy.push({
                    country,
                    names: [rest]
                })
            }
            return groupBy;
        }
    }

    const groupBy = names.reduce(reducer, []);

    console.log('groupBy:', groupBy);
Noitidart
  • 35,443
  • 37
  • 154
  • 323