from Hacker News

Using GroupBy on an array of objects in JavaScript

by saranshk on 12/29/21, 3:39 PM with 31 comments

  • by yashap on 12/29/21, 4:16 PM

    Personally I’d have this return a map instead of an object, so that the keys aren’t forced to be strings. Otherwise seems like a reasonable API, very similar to groupBy in any other moderately functional language, except with the “keys must be strings” restriction inherited from returning a plain object.

    Also, for those thinking JS objects can have non-string keys, they can’t, it just sometimes appears that way due to JS type coercion: https://www.becomebetterprogrammer.com/can-javasscript-objec...

    Edit: as pointed out by shawnz, this isn’t entirely accurate, JS object keys can also be symbols.

  • by ksbrooksjr on 12/29/21, 5:00 PM

    Unfortunately the typescript definitions for these two methods haven't been written yet [1].

    [1] https://github.com/microsoft/TypeScript/issues/47171

  • by jbverschoor on 12/29/21, 4:20 PM

    Oh lord… so you group by a Number, but the map-key becomes a String. Sounds like idiomatic JavaScript
  • by chris-orgmenta on 12/29/21, 11:44 PM

    Great - lodash needed a little less now.

    Though I do often see people using a combination of maps, filters, reduces, lodash functions etc. one by one, rather than doing everything in a single for in loop. In most cases it feels that For In is still the most performant option, as you want to manipulate the data in more ways than just grouping

  • by zackmorris on 12/29/21, 8:53 PM

    For what it's worth, the Laravel PHP framework (no affiliation) has the best introduction to higher-order methods for imperative programmers used to Javascript/C style of anything that I've come across:

    https://laravel.com/docs/master/collections

    Most of these methods are also available as part of the Eloquent ORM, for filtering/reshaping queries before they're executed:

    https://laravel.com/docs/master/eloquent

    Since being exposed to this way of working, I rarely use foreach() anymore, much less for(). The main downside being that I find most other languages tedious to work in now. LINQ in .NET/C# is nice, there might be others.

  • by badjeans on 12/29/21, 6:12 PM

    Hardly shorter than just writing the for loop, i.e. the example in python

        groupByAge = collections.defaultdict(list)
    
        for person in people:
            groupByAge[person["age"]].append(person)
  • by newlisp on 12/29/21, 5:46 PM

    I normally just write

        const groupBy = (fn, arr) => {
            return arr.reduce((o, e) => {
                const k = fn(e)
                if (o[k] !== undefined) o[k].push(e)
                else o[k] = [e]
                return o
            } Object.create(null))
        }
  • by duxup on 12/29/21, 4:13 PM

    I was just doing something like this and thinking “I do this in SQL all the time but users like to change things up so much it should be a native array thing.”
  • by mahesh_rm on 12/29/21, 5:07 PM

    Where was this when I needed it? Happy discovery.
  • by mberning on 12/29/21, 5:42 PM

    I worked on a Ruby gem to add group_by and aggregate_by functions to collections/enumerables. I finished about 1/2 of the functionality and found the implementation to be hateful and thought it would be received poorly. Now seeing this I am second guessing myself.