4

I struggle find a real situation when it's preferable to use a Map instead of a plain array. It just seems harder to use every time.

Did you experiment a suitable case ?

Thank you.

Vivien Adnot
  • 1,157
  • 3
  • 14
  • 30
  • 1
    they serve different purposes. – Daniel A. White Aug 19 '19 at 19:56
  • 2
    Maps and Arrays are not the same at all. Maps allow for selection with keys, and those keys can be any referential or primitive value. Furthermore with WeakMap you can utilize efficient garbage collection. I think the better question is what do you think makes them interchangeable ? – zfrisch Aug 19 '19 at 19:57
  • https://codeburst.io/array-vs-set-vs-map-vs-object-real-time-use-cases-in-javascript-es6-47ee3295329b – Dominik Matis Aug 19 '19 at 19:58
  • 1
    Here's a collection of reasons to use Map. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Objects_and_maps_compared – Jake Worth Aug 19 '19 at 19:58
  • 3
    This would have a been a great question for posterity. It's a shame it got closed. There are plenty of similar highly upvoted questions on S.O. – I wrestled a bear once. Aug 19 '19 at 19:59
  • Maps are more similar to objects than arrays imo. Arrays contain values- maps contain a collection of key-value pairs. – chevybow Aug 19 '19 at 21:46
  • @Iwrestledabearonce. No, it's not a great question. Arrays and maps are totally different, as mentioned in the comments. It's totally unclear how the OP would use them for the same purpose. (Notice that for Map vs object we [do have some](https://stackoverflow.com/q/18541940/1048572) [fine questions](https://stackoverflow.com/q/32600157/1048572)). – Bergi Aug 20 '19 at 02:38

4 Answers4

4

As covered briefly by MDN, Map has a number of technical benefits — while a simple Array or an Object may suffice for simple data structures, oftentimes the increasing complexity of modern web development justifies using something else.

Let's look at a few specific examples:

The keys of a Map can be anything

In both modern libraries as well as webapps, memoization is often used to cut down performance costs of repetitive operations. Briefly, memoization is the act of storing the output of a given function for given inputs after the first run.
Maps are a great candidate for storing this data, since you can use them regardless of what you want to index by.

const cache = new Map();
const input = [2, 3, 2]; // Assuming this is immutable for simplicity

function expensive(n, ...args) {
  if (!args.length) return n;
  return Math.pow(n, expensive(...args));
}

function memoExpensive(arr) {
  const memoResult = cache.get(arr);
  if (memoResult) {
    console.log('used memo', memoResult);
    return memoResult;
  }
  const result = expensive(...arr);
  console.log('calculated', result);
  cache.set(arr, result);
  return result;
}

memoExpensive(input);
memoExpensive(input);

There are cases where you could also use a Symbol and a regular Object, but a Map is more universal in this regard.

Map keys are ordered

For a regular Object, keys are partially ordered (since ECMAScript 2015, before that it was a bit iffy on different engines). Keys keep their order only for string and Symbol keys, while numerical keys are sorted.
When adding keys to an Object in the order c, b, a, 3, 2, 1, the stored order will be 1, 2, 3, c, b, a, for example.

const obj = {};
obj.c = 1;
obj.b = 2;
obj.a = 3;
obj[3] = 4;
obj[2] = 5;
obj[1] = 6;
console.log(Object.keys(obj));

A Map will keep the order of the inserted keys regardless of their type.

const map = new Map();
map.set('c', 1);
map.set('b', 2);
map.set('a', 3);
map.set(3, 4);
map.set(2, 5);
map.set(1, 6);
console.log(Array.from(map.keys()));

Oftentimes this won't matter, especially in casual web dev, but there are numerous notorious cases when the order of the keys does matter.

Map is iterable

While an Array, as brought up in the question, is also iterable, a Map offers a better use-case for key-value mappings than an Object would. Being iterable has a number of benefits, just-in-time execution and guaranteed order being two examples.

const map = new Map()
map.set(document.body, 'blue')
map.set(document.documentElement, 'green')

for (let pair of map) {
  console.log(pair);
}

Other benefits

There are numerous other benefits why you might pick a Map over other alternatives, like performance as covered by Asthmatic, avoiding Object prototype issues, convenience etc.

Hopefully this generic overview has covered most questions you had.

Etheryte
  • 24,589
  • 11
  • 71
  • 116
2

The V8 engine heap isn't very good at managing arrays of objects. If you have an array of 100,000 objects, loop through each object and delete one parameter in the middle then re-add it, the heap size will spike rather than stay constant.

// Spike the memory heap
arr.forEach(obj => {let temp = obj[0]; delete obj[0]; obj[0] = temp})

The reason the heap will spike is because V8 creates intermediate arrays during the forEach loop over the array. Once the array you're looping over becomes massive (eg. 100,000 elements) the memory spike will be too large to handle and could crash the program.

Iterables like Map and Set aren't handled by the engine this way, and you can use a library like iter-tools to get array-like transformation methods for them.

WilliamNHarvey
  • 2,335
  • 2
  • 17
  • 26
  • Intermediate arrays? What for? The only thing you're doing here that's bad for memory usage is using the `delete` operator. Do you have a link to a detailed explanation? – Bergi Aug 20 '19 at 02:41
1

Use a map when you want to create a datastructure mapping keys to values, this has been useful for me i.e. during natural language processing, where we had different commands which had to be bound to keywords, which then can be directly accessed through these keywords - whereas an array is only a container with and index for its content. if you want to access the content of the array you either need to specify the index or run conditional comparisons to find your query

Mesa
  • 11
  • 3
0

Take an example of a car dealership. If you want a list of all the customers, you'd use a plain array, because you just need a list of the elements.

var myArray = ['Walter', 'Jesse', 'Saul'];

But take a situation where you want to store which state the customers are along with their name, then you'd want to use a Map, so that there is correlation between your data (otherwise you just have to random lists of Names and States).

var myMap = new Map([['Walter', 'Arizona'], ['Jesse', 'Florida'], ['Saul', 'Ohio']]);

PS. Excuse my geography, but I'm not from the US. :P

EDIT:Added the correct Map declaration.

Omkar
  • 340
  • 3
  • 14
  • I think they meant Map, the Iterable class. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map – WilliamNHarvey Aug 19 '19 at 21:36
  • @Asthmatic I dont get what you mean. I talked about the same `Map` right? – Omkar Aug 19 '19 at 21:38
  • How is this even a `Map`, aren't you just storing an array of arrays which is super bad practice for object oriented notation? You've got no structure behind your mapping here and, if anything, this approach would lead to more difficulties in data parsing, not less. – ivandov Sep 23 '21 at 10:40
  • @ivandov Not exactly. The constructor is just another way of declaring the map. Check this for more info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#cloning_and_merging_maps – Omkar Sep 25 '21 at 19:47