4 ms·
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
by yashap 5y ago
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-object-keys-be-numbers-or-non-string-values/ 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.
- shawnz 5y agoIt looks like they are also creating a "groupByToMap" for that reason. See: https://github.com/tc39/proposal-array-grouping https://github.com/tc39/proposal-array-grouping Property keys can also be symbol objects and it seems like that's supported by the groupBy function in addition to strings, see: https://tc39.es/proposal-array-grouping/ https://tc39.es/proposal-array-grouping/
- yashap 5y agoAh fair enough!
- saranshk 5y agoupdated the post with groupByToMap, Thanks for pointing that out.
- roebk 5y agoI wonder if groupBy should have had some sort of into argument. Otherwise, we may end up with four groupBy methods. groupBy, groupByToMap, groupByToWeakMap and groupByToRecord (should records land). Edit: this has already been discussed https://github.com/tc39/proposal-array-grouping/issues/3 https://github.com/tc39/proposal-array-grouping/issues/3
- beebeepka 5y agoKey strings can also contain emojis. Not that I would recommend it in most situations
- VWWHFSfQ 5y agoit's just utf8 bytes right
- masklinn 5y ago> Otherwise seems like a reasonable API, very similar to groupBy in any other moderately functional language Though lots of them implement the less useful but stream-able groupBy which only groups siblings matching the predicate (or key function).
- jraph 5y agoI found this article a bit verbose (maybe because I'm already familiar with the topic) and yet missing three "key" (ah ah) points: - one can get the keys of an object by using Object.keys or a for-in loop and notice that keys are always strings, even when using arrays. - the object definition syntax [1] is set to define property strings by the standard (and symbols). You can (and probably should) experiment, but the spec will tell you what happens anyway with 100% certainty (except for implementation bugs, but that's not what we are looking for). - the definitive answer to "what kind of value an object key can be in Javascript?" is given by the section "The Object Type" of the ECMAScript standard [2]: > Properties are identified using key values. A property key value is either an ECMAScript String value or a Symbol value. All String and Symbol values, including the empty String, are valid as property keys. A property name is a property key that is a String value. Experimentation helps anchoring things in memory and building intuition, as well as getting into things. Inviting people to experiment by themselves and not blindly trust what they read is a fantastic advice. I do experiment a lot myself. However, experimentation is not the best way to "prove" things (contrary to what the article states). Definitive answers should be found in specifications and documentations (or implementation sources). No amount of experimentation will be enough to convince me of "See? I did this this and this, and it's always strings". The article is well written, the same thing with these references to the spec would make it strong and irrefutable. [1] https://tc39.es/ecma262/#sec-object-initializer-static-semantics-propname https://tc39.es/ecma262/#sec-object-initializer-static-seman... [2] https://tc39.es/ecma262/#sec-object-type https://tc39.es/ecma262/#sec-object-type
- wereHamster 5y agoA «group by» function requires keys to be comparable (for equality). You can see this when you look at the type signatures of «group by» functions in any strongly typed language or library. They either require a comparator to be provided, or infer it from the context (type classes in Haskell). JavaScript has quite intuitive equality for primitive types (strings, symbols), but nothing that would be natural for complex objects. Consider this array: [{ key: {}, foo: 1 }, { key: {}, foo: 2 }], there are multiple answers how a Map can look when you group by 'key'. Both comparing the keys using '===' and deep equality are valid options, depending on needs.
- yashap 5y agoJS maps already have a well defined way that they do key equality: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#key_equality https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... It's basically just strict equality (===), except NaN === NaN is false, while they're considered equal for map keys. So in your example, you'd have 2 entries, since {} !== {}. It sounds like they're going to implement `groupByToMap` as well as `groupBy`, and I assume `groupByToMap` will just use the normal map key equality rules, and I guess the "first" key matching that equality will be used for the grouping.
- wereHamster 5y agoMy point is that you can't override what equality implementation groupByToMap will use, which makes it much less useful. See for example https://gcanti.github.io/fp-ts/modules/NonEmptyArray.ts.html#group https://gcanti.github.io/fp-ts/modules/NonEmptyArray.ts.html..., where you can supply your own equality function…