loading...

JS array vs object vs map

bernardwiesner profile image Bernard Wiesner ・3 min read

Like other programming languages, JS has data structures, such as arrays and maps. Maps are key pair entries or associative arrays however maps can cause confusing in JS, lets first take a look at using an arrays as a map:

let students = []
students[0] = 'Mark'
students[1] = 'Mia'

console.log(students)

If we check the contents of the students array we get this:

Alt Text

Now lets take a look at an object:

let students = {}
students[0] = 'Mark'
students[1] = 'Mia'

console.log(students)

Lets check the contents of the object:

Alt Text

Looks almost same as the array, both have key pairs. Lets mix things up a little, lets say our keys are dynamic and we want to access the value of the student by its id. Lets do this with an array:

let students = []
students[0] = 'Mark'
students[10] = 'Mia'

console.log(students.length)
// 11

Wait what? There are 11 students? Since we are using array indexes as dynamic keys this is causing empty slots.

If we would loop and console log every student, we would get this:

for(student of students){
  console.log(student)
}

Alt Text

9 undefined entries, this could cause a lot of issues related to performance and integrity. So we should not use arrays with dynamic keys, having empty slots is not good. Another reason to not use arrays as maps is that you cant assign non numeric indexes on arrays as keys.

Lets do the same with an object:

let students = {}
students[0] = 'Mark'
students[10] = 'Mia'

console.log(Object.keys(students).length)
// 2

Works fine, only 2 entries, no more empty slots and now we can access the student directly by its id:

console.log(students[10])
// Mia

However what happens when we invert the order of the ids?

let students = {}
students[10] = 'Mia'
students[0] = 'Mark'

console.log(students)
// Object { 0: "Mark", 10: "Mia" }

Oh, the insertion order isn't maintained in the object. It seems like they are getting sorted numerically. Ok, so lets use strings.

let students = {}
students['10'] = 'Mia'
students['0'] = 'Mark'

console.log(students)
// Object { 0: "Mark", 10: "Mia" }

Same result... What about if we use alphabetic characters will they get sorted?

let students = {}
students['key-10'] = 'Mia'
students['key-0'] = 'Mark'

console.log(students)
// Object { "key-10": "Mia", "key-0": "Mark" }

Oh, they didn't get sorted this time. So if we use non numeric characters the insertion order is kept.

In JS there exist 2 different types of maps, maps related to regular objects and maps related to the Map object.

Lets take a look at the new Map object in JS introduced in ES6.

let students = new Map()
students.set(10, 'Mia') 
students.set(0, 'Mark') 

console.log(students)
// Map { 10 → "Mia", 0 → "Mark" }

Oh the insertion order was preserved. We can also access the id of the student directly.

console.log(students.get(10))
// Mia

So what to take from this?

  1. Dont use JS arrays as a map or associative array.
  2. If you need to access a value by key and don't care about insertion order, you can go with a regular object.
  3. If you care about insertion order go with a Map object.

Beware, ES6 Map object may not work with certain things such as v-for in vue 2.

Discussion

markdown guide