Extend keys() and other generator methods of Map class in javascript
P粉613735289
P粉613735289 2024-02-04 00:24:18
0
2
471

I needed to use an object as the key for my map, so I extended the map class that stringified the passed object as follows

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, so I can do something similar

* keys() {
   const keysArr = [...super.keys()]
   for (const key of keysArr){
      yield JSON.parse(key)
   }
}

But this causes me to load all the keys I wish to avoid, is there a better way?

edit: While Map does have objects as keys, it only checks objects by reference. for 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

I also need the second one console.log returns 123

P粉613735289
P粉613735289

reply all(2)
P粉211273535

In case anyone stumbles here in the future, there is a Phase 3 proposal If approved, it will add syntactic sugar for iterators so that you can do things like:

class CoordMapper extends Map {
  *keys() {
    yield* super.keys().map(key => JSON.parse(key));
  }
}

Try this (this doesn't work yet):

console.config({ maximize: true });

class CoordMapper extends Map {
  set(k, v) {
    return super.set(JSON.stringify(k), v)
  }
  get(k) {
    return super.get(JSON.stringify(k));
  }
  *keys() {
    console.log(super.keys())
    yield* super.keys().map(JSON.parse);
  }
}

const c = new CoordMapper();

c.set({ foo: 'bar' }, 0);
c.set({ baz: 42 }, 1);
c.set({ qux: { lorem: 'ipsum' } }, [null, undefined]);

for (const key of c.keys()) {
  console.log(key);
}
sssccc
P粉311089279

Instead of collecting all parent values ​​into an array, iterate over them directly:

* keys() {
   const parentKeyIterator = super.keys();
   for (const key of parentKeyIterator){
      yield JSON.parse(key)
   }
}

This way, the laziness of the iterator is preserved: every time next() is called on the extended iterator, it will call next( on the parentKeyIterator ) once, then reaches the yield statement, then pauses.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template