Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

don't prefer Object over Map #33

Closed
@mfulton26

Description

@mfulton26

I suggest renaming groupBy and groupByToMap to groupByToObject and groupBy respectively or dropping support for an object altogether.

  1. there are various reasons to prefer Map over Object

    reasons from MDN
    Map Object
    Accidental Keys A Map does not contain any keys by default. It only contains what is explicitly put into it.

    An Object has a prototype, so it contains default keys that could collide with your own keys if you're not careful.

    Note: As of ES5, this can be bypassed by using {{jsxref("Object.create", "Object.create(null)")}}, but this is seldom done.

    Key Types A Map's keys can be any value (including functions, objects, or any primitive). The keys of an Object must be either a {{jsxref("String")}} or a {{jsxref("Symbol")}}.
    Key Order

    The keys in Map are ordered in a simple, straightforward way: A Map object iterates entries, keys, and values in the order of entry insertion.

    Although the keys of an ordinary Object are ordered now, this was not always the case, and the order is complex. As a result, it's best not to rely on property order.

    The order was first defined for own properties only in ECMAScript 2015; ECMAScript 2020 defines order for inherited properties as well. See the OrdinaryOwnPropertyKeys and EnumerateObjectProperties abstract specification operations. But note that no single mechanism iterates all of an object's properties; the various mechanisms each include different subsets of properties. ({{jsxref("Statements/for...in", "for-in")}} includes only enumerable string-keyed properties; {{jsxref("Object.keys")}} includes only own, enumerable, string-keyed properties; {{jsxref("Object.getOwnPropertyNames")}} includes own, string-keyed properties even if non-enumerable; {{jsxref("Object.getOwnPropertySymbols")}} does the same for just Symbol-keyed properties, etc.)

    Size

    The number of items in a Map is easily retrieved from its {{jsxref("Map.prototype.size", "size")}} property. The number of items in an Object must be determined manually.
    Iteration A Map is an iterable, so it can be directly iterated.

    Object does not implement an iteration protocol, and so objects are not directly iterable using the JavaScript for...of statement (by default).

    Note:

    • An object can implement the iteration protocol, or you can get an iterable for an object using Object.keys or Object.entries.
    • The for...in statement allows you to iterate over the enumerable properties of an object.
    Performance

    Performs better in scenarios involving frequent additions and removals of key-value pairs.

    Not optimized for frequent additions and removals of key-value pairs.

  2. destructuring and transformation for JSON stringification can be accomplished from a Map easily enough using Object.fromEntries:

    const { even, odd } = Object.fromEntries(
      array.groupBy((num, index, array) => {
        return num % 2 === 0 ? "even" : "odd";
      })
    );
  3. groupBy (to a null-prototype object) may set a precedence for future features to avoid defaulting to more proper keyed collections like Map and Set and use objects and arrays instead; these have been used historically and continue to be used prevalently (from what I can tell) even when there are now these more optimized/appropriate collections available

in short, making it easy for developers to use a Map seems like a win to me and paves the way for more rich data structures and utilities using them and for those use cases where an Object is wanted (destructuring and JSON stringification) then there is a built-in way to quickly, efficiently, and (IMO) ergonomically transform the returned Map to an Object. If further convenience/ergonomics is desired then a groupByToObject method could still be provided while the shorter go-to method groupBy would return a Map as the "preferred" type to work with

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions