Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

JS iterate array items and group them in new array by property

I have an array of objects

    listOfItems: any[] = [
      {text: 'Hola', group: 'espanian'},
      {text: 'Hello', group: 'english'},
      {text: 'How are you', group: 'english'},
      {text: 'Tere', group: 'estonian'},
    ]

I would like to iterate over an array and create another array with categorized objects

    groups: any[] = [
    [
      { name: 'english', 
        items: [
           {text: 'Hello', group: 'english'},
           {text: 'How are you', group: 'english'},
        ]
      },
      { name: 'espanian', 
        items: [
           {text: 'Hola', group: 'espanian'}
        ]
      },
      { name: 'estonian', 
        items: [
           {text: 'Tere', group: 'estonian'}
        ]
      },
    ]

What is the most dynamic way to do it?
The number of groups could be over 30, so I would like to avoid doing if or equals checks inside the loop

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I mean dynamic – is basically without any explicit checks
like item.group = ‘english’

I have tried to achieve something similar with

      let result: any = [];
      this.listOfItems.forEach(p => {
        var key = p.group;
        result[key] = result[key] || [];
        result[key].push(p);
      })

however the result is not exactly what I am looking for

[
   {'english': [
             {text: 'Hello', group: 'english'},
             {text: 'How are you', group: 'english'},
            ]
   }, 
   {'espanian': [
             {text: 'Hola', group: 'espanian'},
            ]
   },
]

>Solution :

  1. Why any[]?
  2. Maps are really great for these types of data manipulations. Check it out:
interface Item {
    text: string;
    group: string;
}

interface Categorized {
    name: string;
    items: Item[];
}

const itemList: Item[] = [
    { text: 'Hola', group: 'espanian' },
    { text: 'Hello', group: 'english' },
    { text: 'How are you', group: 'english' },
    { text: 'Tere', group: 'estonian' },
];

const categorize = (list: Item[]): Categorized[] => {
    const map: Record<string, Categorized> = {};

    list.forEach((item) => {
        if (!map[item.group]) {
            map[item.group] = { name: item.group, items: [item] };
            return;
        }

        map[item.group].items.push(item);
    });

    return Object.values(map);
};

console.log(categorize(itemList));

We’re only using one loop.

Compiled:

var itemList = [
    { text: 'Hola', group: 'espanian' },
    { text: 'Hello', group: 'english' },
    { text: 'How are you', group: 'english' },
    { text: 'Tere', group: 'estonian' },
];
var categorize = function (list) {
    var map = {};
    list.forEach(function (item) {
        if (!map[item.group]) {
            map[item.group] = { name: item.group, items: [item] };
            return;
        }
        map[item.group].items.push(item);
    });
    return Object.values(map);
};
console.log(categorize(itemList));
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading