I need to use an object as keys for my map, therefore I extended the map class that stringifies the object passed, like so
class CoordMapper extends Map {
set = (k: ISquareCoordinate, v: Array<ISquareCoordinate>) => {
const stringifiedKey = JSON.stringify(k)
return super.set(stringifiedKey,v)
}
get = (k: ISquareCoordinate) => {
const stringifiedKey = JSON.stringify(k)
return super.get(stringifiedKey)
}
}
As far as I understand keys(), values() and entries() are generator methods, therefore I can do something like
* keys() {
const keysArr = [...super.keys()]
for (const key of keysArr){
yield JSON.parse(key)
}
}
But this causes me to load all the keys which I wish to avoid, is there a better way?
EDIT:
While Map does take in objects as keys but it only checks objects by reference. As an example
let newMap = Map()
const obj1 = {'a': 1, 'b' :2}
newMap.set(obj1, 123)
const copyObj1 = {...obj1}
console.log(newMap.get(obj1)) //returns 123
console.log(newMap.get(copyObj1)) //returns undefined
And i need the second console.log
to return 123 aswell
2
Answers
Rather than collecting all the parent values into an array, just iterate over them directly:
That way, the laziness of the iterator is retained: each time
next()
is called on your extended iterator, it will callnext()
onparentKeyIterator
once, then reach youryield
statement, and pause.Just in case someone stumble here in the future, there’s a stage-3 proposal which, if approved, would add syntactic sugar for iterators so that you can do something like this:
Try it (this doesn’t work yet):