1

Is there any way that I can insert an new element into a Map before of or after an existing key? as for Array would be: arr.splice(<POSITION>, 0, <NEW ELEMENT>);

Thanks!

PaRoJa
  • 303
  • 3
  • 13
  • Can I ask why? This sounds like a strange request. –  Dec 15 '17 at 08:13
  • you can traverse and do it, have you tried this or this is your question? – Deepak Jha Dec 15 '17 at 08:14
  • No is the short answer, maps don't necessarily maintain position. – user184994 Dec 15 '17 at 08:14
  • Are you asking about [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) or [object literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)? – str Dec 15 '17 at 08:21
  • Asking about Map. Looks like the only way is .set() a new element and then sort – PaRoJa Dec 15 '17 at 08:31
  • You could re-create the map on every insertion and just insert the elements in the order you want. Depending on whether insertion or iteration happens more often, that could be better. – str Dec 15 '17 at 09:03

1 Answers1

1

general theory

A Map does –unlike an array– not have the semantics of “order”.

It's designed to be most efficient for storing&retrieving values for specific keys. (In fact, it's internal implementation does some structuring/ordering specifically optimized for that, “b-tree” being the keyword here.

javascript implementation

Despite all that, mozilla docs say:

A Map object iterates its elements in insertion order — a for...of loop returns an array of [key, value] for each iteration.

update: The official ECMA-262 standard confirms this.

personally, I am guessing, implementors will keep a separate index for order-of-entry and a b-tree for most efficient singular access.

Based on this, what you would have to do is essentially, treating the map like an immutable object, and creating a new one from it:

  1. iterate over the prior map
  2. add each element to a new map. – when the right time comes, insert your element. – Keep iterating for the rest of it
  3. assign your new element to the name of the old one.

I don't now your specific use case, but perhaps your problems could also be solved by sort Iteration to specific criteria right when iterating over it.

Frank N
  • 9,625
  • 4
  • 80
  • 110
  • This is wrong, the `Map` that you linked actually *does* have an order. It always iterates the elements in insertion order. – str Dec 15 '17 at 08:22
  • @Frank Nocke I see developer.mozilla.org says "A Map object iterates its elements in insertion order", so I guess the only way, as you said is to sort the map – PaRoJa Dec 15 '17 at 08:29
  • Thank you both <3, I adjusted my answer! – Frank N Dec 15 '17 at 09:26
  • This is still wrong: "A Map does –unlike an array– not have the semantics of 'order'." While MDN is great for web developers, it is not an authoritative resource. But most articles on MDN link to the actual one in the "Specifications" section. For example, the [authoritative specification of `Map`](https://tc39.github.io/ecma262/#sec-map-objects). In fact, you can also read some implementation details. – str Dec 15 '17 at 12:33
  • @str The spec does not have any implementation details, it only states *behavioural* details. But yeah, maps do ("somehow") keep insertion order and the algorithm described in the answer is the only way to "insert in the middle". – Bergi Dec 15 '17 at 14:01
  • @Bergi I was relating to "Map object must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection." Yes that is not very specific, but not just behavioural either. – str Dec 15 '17 at 14:14
  • Update: found it in [the official spec](http://www.ecma-international.org/ecma-262/6.0/#sec-map.prototype.foreach) I think… – Frank N Dec 15 '17 at 14:55