JavaScript and Object Keys
Hello 👋 In this post we will try to use objects in a different wrong way 😃 by implement a frequency array in javascript. But before we dive into this, We will discover what's the frequency array?
Frequency Array on a sorted array
For example, If you have an array like this const arr = [1,2,2,3,3,4];
and you want to count occurrences of each element, then you can iterate over the values and store them as keys of object and its value increasing according to the number of occurrences in the remainig array. And this is called a frequency array. The code below go through what I'm saying (Please Don't do this again):
const arr = [1, 2, 2, 3, 3, 4];
const result = {};
for (let i = 0; i < arr.length; i++) {
if (arr[i] in result) result[arr[i]]++;
else result[arr[i]] = 1;
}
console.log(result); // {1: 1, 2: 2, 3: 2, 4: 1}
Wow! that's cool and Right! But No. That's wrong! Why??
You're write this code and seems that works well, but try to add -1
to the first of your array, then you'll discover that the final result is {1: 1, 2: 2, 3: 2, 4: 1, -1: 1}
, Wait... But Why? You're wondering why the -1
is in the end of the result object and you know the object in javascript sorting the keys by default. (Ummm not exactly!)
Objects' Keys in Javascript are strings
and symbols
only, you can't use any primitive values as keys except strings
and symbols
So the keys in your result aren't numbers
, they're parsed to strings
before storing as keys in object, but "-1" < "1" === true
so still why -1
moved to the end?!
Note: Symbol
Can be a key for objects, but it doesn't work like strings
. Read more...
How Javascript objects order their keys?
Keys in Javascript objects are three types, +integer-like (0,1,2,3), strings, and symbols. And the order goes:
- +Integer-like in ascending order.
-1
like our previous example or negatives in general aren't valid as an index, there's no-1
index, So they're ordered asstrings
. - Strings in order of created, without any sort or comparison.
- Symbols in order of created, without any sort or comparison.
Okay, So in our previous example, we figured out what happens while getting the result, Right? But what if we want to get the right order?
new Map()
To achieve our frequency array respecting keys insertion order we can use new Map()
which allows keys to be anytype, so the code for this will be like this:
const arr = [-1, 1, 2, 3, 4, 3, 2];
var result = new Map();
for (let i = 0; i < arr.length; i++) {
if (result.has(arr[i])) {
result.set(arr[i], result.get(arr[i]) + 1);
} else result.set(arr[i], 1);
}
console.log(result); //Map(5)Â {-1 => 1, 1 => 1, 2 => 2, 3 => 2, 4 => 1}
Then we can iterate over it using forEach
method.