5 ms·
Nice, the JS standard library is gradually getting functions I take for granted in ClojureScript. :) I noticed this part in the proposal groupBy calls callb
by koito17 3y ago
Nice, the JS standard library is gradually getting functions I take for granted in ClojureScript. :)
I noticed this part in the proposal
groupBy calls callbackfn once for each element in items, in ascending order, and constructs a new Object of arrays. Each value returned by callbackfn is coerced to a property key
Does JS allow arbitrary objects as keys? I am asking because `group-by` in ClojureScript is quite flexible. e.g. you can find anagrams like so
(def words ["meat" "mat" "team" "mate" "eat" "tea"])
(group-by set words) ; set is a function that creates sets from collections
;; => {#{\a \e \m \t} ["meat" "team" "mate"]
;; #{\a \m \t} ["mat"]
;; #{\a \e \t} ["eat" "tea"]}
I am wondering how one could translate this using Object.groupBy as specified in the proposal.
- tibbar 3y agoJS does indeed allow mapping arbitrary objects to keys. However, it is the memory address of the object that is hashed, not the semantic value. So, for example, if you do: objects = {} items1 = ["a", "b"] items2 = ["a", "b"] objects[items1] = 1 objects[items2] = 2 then objects[items1] will return 1, and objects[items2] will return 2, but objects[items1] !== objects[items2]. EDIT: Sorry, this only works for dictionaries that are Maps, not Objects! See the responses. My fuzzing about in the console led me astray; you should start with `objects = new Map()` instead of `objects = {}`.
- thegeomaster 3y agoThis is not true. I think you're confusing JS objects with Maps. This will just coalesce the key to string and overwrite one element of the object with the other. With a map it works like you described: objects = new Map() items1 = ["a", "b"] items2 = ["a", "b"] objects.set(items1, 1) objects.set(items2, 2)
- mediumdeviation 3y agoActually that only works with Map. For plain objects the key is always the stringified cast of the key. > o = { [{}]: 1 } { '[object Object]': 1 } > k = { toString() { return 'a' } } { toString: [Function: toString] } > o = { [k]: 1 } { a: 1 }
- aragonite 3y agoRight ... and it seems it's not even possible to simulate object keys using Proxy traps: new Proxy( {}, { get(target, property) { return typeof property }, }, )[{}] === 'string'
- koito17 3y agoAh, I didn't know Map in JavaScript allowed arbitrary keys whereas Object always serializes to strings. I guess that is the reason for having a Map.groupBy in the proposal. Thanks for taking the time to explain, everybody
- moritzwarhier 3y agoJS allows arbitrary values (including objects/references) as keys in Maps, but not in objects, there it is cast to string by default (e.g. "object [Object]", "null" or "undefined", this is not intended usage of course). The symbol primitive is also allowed as an object key, using square bracket access. And arrays are "exotic objects" that have some special behaviors around their keys (auto-updating length property)
- ForkMeOnTinder 3y ago> Does JS allow arbitrary objects as keys? Object doesn't, but Map does. It's generally a good idea to use Map anyway for dynamic keys.
- deleted 3y ago[deleted]
- freedomben 3y agoYou ClojureScript people seem to be stalking me :-D I've wanted to learn Clojure for years but haven't found the right reason, until discovering Logseq. Such a cool language!
- deleted 3y ago[deleted]