name
name

Reputation: 49

Javascript map sorted by update/insertion order

In javascript, is there a data structure that tracks insertion/update order? for instance, if you have:

map[a]=1
map[b]=2
map[c]=3

I would want to get the keys in order a,b,c but if I had

map[a]=1
map[b]=2
map[c]=3
map[b]=4

I would want the keys in order a,c,b since b was last updated.

I'm currently doing this with a js object and a sorted list to track update order. Is there a better way to do this?

Upvotes: 0

Views: 1399

Answers (2)

dwhieb
dwhieb

Reputation: 1836

Maps retain the insertion order of their keys:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

Any iterator methods for Maps will iterate over the keys in insertion order.

Objects do not guarantee that the insertion order of their keys is preserved:

Does JavaScript guarantee object property order?

Neither Maps nor Objects track update order. You'd need a custom solution for this, probably using a Proxy.

Upvotes: 0

adiga
adiga

Reputation: 35243

You could create a Proxy object with a trap for set. Use a set to keep track of all the keys in the object. Every time you set a property, you can delete the key from the set before adding it. This ensures that the key just updated is always enumerated at the end.

A Set is used because, integer-like keys are enumerated before the string keys, irrespective of the order they are inserted. A set will keep the order of insertion. As suggested by @Kaiido, you can add an ownKeys trap. When the keys of the object are requested, then will be returned from the Set and the keys will be returned in the order of the Set.

const createHandler = (keys = new Set) => ({
  set(obj, prop, value) {
    keys.delete(prop);
    keys.add(prop);
    return Reflect.set(...arguments)
  },
  ownKeys(obj) {
    return Array.from(keys)
  }
})

const map = new Proxy({}, createHandler())

map.a = 1,
map.b = 2;
map[1] = "integer-like key"

console.log(Object.keys(map))

map.c = 3;
map.b = 5

console.log(Object.keys(map))

Upvotes: 2

Related Questions