Search code examples
javascriptlodash

group object by attribute, extracting other attributes in a child of grouped result


In our app we have an autosuggest from a search input. The returned array corresponds to this model.

AutoSuggest[] = 
[
    {category: "CAR", type: "COMMON", suggests: ['ford', 'jeep']},
    {category: "TRAVEL", type: "SHORT", suggests: ['tokyo', 'paris', 'london']},
    {category: "TRAVEL", type: "LONG", suggests: ['costa rica', 'greenland']}}
]

We would like to obtain a result which merges the category but keep values and type separate as two different arrays entries. It would look like this:

[
    {
        category: "CAR",
        values: [
            { type: "COMMON", suggests: ['ford', 'jeep'] }
        ]
    },
    {
        category: 'TRAVEL',
        values: [
            { type: "SHORT", suggests: ['tokyo', 'paris', 'london'] },
            { TYPE: "LONG", suggests: ['costa rica', 'greenland'] }
        ]
    }
]

Trying with lodash groupBy, we simply got our suggests placed into CAR and TRAVEL objects. But it doesn't fit our needs since we need to do some "extracting" part of original object.


Solution

  • You could use a hash table for grouping into same categories.

    var data = [{ category: "CAR", type: "COMMON", suggests: ['ford', 'jeep'] }, { category: "TRAVEL", type: "SHORT", suggests: ['tokyo', 'paris', 'london'] }, { category: "TRAVEL", type: "LONG", suggests: ['costa rica', 'greenland'] }],
        hash = Object.create(null),
        grouped = [];
    
    data.forEach(function (o) {
        if (!hash[o.category]) {
            hash[o.category] = { category: o.category, values: [] };
            grouped.push(hash[o.category]);
        }
        hash[o.category].values.push({ type: o.type, suggests: o.suggests });
    });
    
    console.log(grouped);
    .as-console-wrapper { max-height: 100% !important; top: 0; }