Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create array of objects by key from array of objects

There are a lot of questions like this on here, but I couldn't find one that matched my needs. I'm looking for a relatively simple solution on how to stack objects in an array into new arrays based on a key.

In the example data we're grouping the objects by their "ship" key.

Original data:

 var myObjArray = [
    {
        name:'Malcolm Reynolds',
        ship:'Serenity'
    },
    {
        name: 'Carmen Ibanez',
        ship: 'Rodger Young',
    },
    {
        name: 'Zander Barcalow',
        ship: 'Rodger Young',
    },
    {
        name:'Hoban Washburne',
        ship:'Serenity'
    },
    {
        name:'James Kirk',
        ship:'USS Enterprise'
    }
];

Restructured Data:

    var myNewObjArray = [
    [{
        name:'Malcolm Reynolds',
        ship:'Serenity'
    },
    {
        name:'Hoban Washburne',
        ship:'Serenity'
    }],
    [{
        name: 'Carmen Ibanez',
        ship: 'Rodger Young',
    },
    {
        name: 'Zander Barcalow',
        ship: 'Rodger Young',
    }],
    {
        name:'James Kirk', // optionally also stick in an array
        ship:'USS Enterprise'
    }
];

If anyone has a solution for this I'd appreciate it, my current attempt is sloppy to say the least.

like image 634
Ian Gray Avatar asked Oct 28 '25 07:10

Ian Gray


1 Answers

You could take an object for and the ship value as key for the same group. For the result take only the values of the object.

var data = [{ name: 'Malcolm Reynolds', ship: 'Serenity' }, { name: 'Carmen Ibanez', ship: 'Rodger Young' }, { name: 'Zander Barcalow', ship: 'Rodger Young' }, { name: 'Hoban Washburne', ship: 'Serenity' }, { name: 'James Kirk', ship: 'USS Enterprise' }],
    grouped = Object.values(data.reduce((r, o) => {
        if (!r[o.ship]) {
            r[o.ship] = o;
            return r;
        }
        if (!Array.isArray(r[o.ship])) r[o.ship] = [r[o.ship]];
        r[o.ship].push(o);
        return r;
    }, {}));

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

An approach with a Map

var data = [{ name: 'Malcolm Reynolds', ship: 'Serenity' }, { name: 'Carmen Ibanez', ship: 'Rodger Young' }, { name: 'Zander Barcalow', ship: 'Rodger Young' }, { name: 'Hoban Washburne', ship: 'Serenity' }, { name: 'James Kirk', ship: 'USS Enterprise' }],
    grouped = Array.from(
        data
            .reduce((m, o) => m.set(o.ship, [...(m.get(o.ship) || []), o]), new Map)
            .values(),
        a => a.length === 1 ? a[0] : a
    );

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 82
Nina Scholz Avatar answered Oct 31 '25 01:10

Nina Scholz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!