📄 Table of Contents

▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ ✦ ✦ ✦ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬

◉ How an array in JS is different from array in other languages

We can store Numbers, Strings and Boolean in a single array, without worrying about its data-type.

Declaration of an Array
There are basically two ways to declare an array.
Example:

var House = [ ];         // method 1 (preferred method)
var House = new array(); // method 2

But generally method 1 is preferred over the method 2.

Let us understand the reason for this.

// Initializing while declaring
var house = new Array(10, 20, 30, 40, 50);
# Creates an array having elements 10, 20, 30, 40, 50


var house1 = new Array(5);
# Creates an array of 5 undefined elements

As shown in above example the house contains 5 elements i.e. (10 , 20, 30, 40, 50) while house1 contains 5 undefined elements instead of having a single element 5. Hence, while working with numbers this method is generally not preferred but it works fine with Strings and Boolean.

◉ Check if variable is an Array in JavaScript?

Method 1: Using the isArray method

Array.isArray(variableName)

It returns a true boolean value if the variable is an array and false if it is not.

Array.isArray([1, 2, 3]);  // true
Array.isArray({foo: 123}); // false
Array.isArray('foobar'); // false
Array.isArray(undefined); // false

Method 2: Using the instanceof operator

variable instanceof Array

The operator returns a true boolean value if the variable is same as what is specified (here an Array) and false if it is not.

let arr = [1, 2, 3];
alert( arr instanceof Array ); // true
alert( arr instanceof Object ); // true

Please note that arr also belongs to the Object class. That’s because Array prototypically inherits from Object.

Normally, instanceof examines the prototype chain for the check. We can also set a custom logic in the static method Symbol.hasInstance.

👉 instanceof vs isArray()

Method 3: Checking the constructor property of the variable

This is the fastest method on Chrome, and most likely all other browsers. All arrays are objects, so checking the constructor property is a fast process for JavaScript engines.

variable.constructor === Array

This becomes true if the variable is same as what is specified (here an Array) and false if it is not.

let str = [1,2,3,4,5];str.constructor === Array;  # true
str.constructor === Object; # false

◉ Basic Array Sorting

const foo = [99, 11, 41, 'zzz', 'aaa'];
foo.sort(); // returns [ 11, 41, 99, 'aaa', 'zzz' ]
const bar = [5, 18, 32, new Set, { user: 'anil kumar' }];
bar.sort(); // returns [ 18, 32, 5, { user: 'anil kumar' }, Set {} ]

You may be wondering why 32 comes before 5. Not logical, huh? Well, actually it is. This happens because each element in the array is first converted to a string, and "32" comes before "5" in Unicode order.

It’s also worth noting that unlike many other JavaScript array functions, Array.sort actually changes, or mutates the array it sorts.

const foo = ['I love javascript', 37, 9, 5, 17];
foo.sort(); // foo array is modified
console.log(foo); // shows [ 17, 37, 5, 9, 'I love javascript' ]

To avoid this, you can create a new instance of the array to be sorted and modify that instead. This is possible using an array method that returns a copy of the array. For example, Array.slice:

const sortedFoo = foo.slice().sort(); // a new instance of the foo array is created and sorted

Or if you prefer a newer syntax, you can use the spread operator for the same effect:

const sortedFoo = [...foo].sort(); 
// a new instance of the foo array is created and sorted

The output is the same in both cases:

console.log(foo);        // ['I love javascript', 37, 9, 5, 17];
console.log(sortedFoo); // [ 17, 37, 5, 9, 'I love javascript' ]

However, using Array.sort alone wouldn’t be very useful for sorting an array of objects. Thankfully, the function takes an optional compareFunction parameter, which causes the array elements to be sorted according to the return value of the compare function.

Using Compare Functions to Sort

Report Advertisement

  1. less than 0 — foo comes before bar
  2. greater than 0 — bar comes before foo
  3. equal to 0 — foo and bar are left unchanged with respect to each other.

Let’s look at a simple example with an array of numbers:

const nums = [79, 48, 12, 4];function compare(a, b) {
if (a > b) return 1;
if (b > a) return -1;
return 0;
}
nums.sort(compare);
// => 4, 12, 48, 79

We can refactor this a little, as subtracting a from b will also give us the return value:

function compare(a, b) {
return a - b;
}

This is now a good candidate for an arrow function:

nums.sort((a, b) => a - b);

If you’re not familiar with arrow functions, you can read more about them here: ES6 Arrow Functions: Fat and Concise Syntax in JavaScript.

How to Sort an Array of Objects in JavaScript

const singers = [
{ name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },
{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 },
{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },
{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
];

We can use the following compare function to sort this array of singers according to their band:

function compare(a, b) {
// Use toUpperCase() to ignore character casing
const bandA = a.band.toUpperCase();
const bandB = b.band.toUpperCase();
let comparison = 0; if (bandA > bandB) {
comparison = 1;
} else if (bandA < bandB) {
comparison = -1;
}
return comparison;
}
singers.sort(compare);/* returns [
{ name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },
{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },
{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }
] */

To reverse the sorting order, you can invert the return value of the compare function:

function compare(a, b) {
...
//invert return value by multiplying by -1
return comparison * -1;
}

Creating a Dynamic Sorting Function

const singers = [
{ name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },
{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 },
{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },
{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
];
function compareValues(key, order = 'asc') {
return function innerSort(a, b) {
if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
// property doesn't exist on either object
return 0;
}
const varA = (typeof a[key] === 'string')
? a[key].toUpperCase() : a[key];
const varB = (typeof b[key] === 'string')
? b[key].toUpperCase() : b[key];
let comparison = 0;
if (varA > varB) {
comparison = 1;
} else if (varA < varB) {
comparison = -1;
}
return (
(order === 'desc') ? (comparison * -1) : comparison
);
};
}

And this is how you’d use it:

// array is sorted by band, in ascending order by default
singers.sort(compareValues('band'));
// array is sorted by band in descending order
singers.sort(compareValues('band', 'desc'));
// array is sorted by name in ascending order
singers.sort(compareValues('name'));
// array is sorted by date if birth in descending order
singers.sort(compareValues('born', 'desc'));

In the code above, the hasOwnProperty method is used to check if the specified property is defined on each object and has not been inherited via the prototype chain. If it’s not defined on both objects, the function returns 0, which causes the sort order to remain as is (i.e. the objects remain unchanged with respect to each other).

The typeof operator is also used to check the data type of the property’s value. This allows the function to determine the proper way to sort the array. For example, if the value of the specified property is a string, a toUpperCase method is used to convert all its characters to uppercase, so character casing is ignored when sorting.

You can adjust the above function to accommodate other data types, and any other needs your script may have.

String.prototype.localeCompare()

This method returns a number indicating whether a string comes before, after, or is the same as a given string in the sort order. It enables a case-insensitive sort of an array:

['bjork', 'Bjork', 'Björk'].sort();
// [ 'Bjork', 'Björk', 'bjork' ]
['bjork', 'Bjork', 'Björk'].sort((a, b) => a.localeCompare(b));
// [ 'bjork', 'Bjork', 'Björk' ]

In terms of our compareValues function, that means we could write:

function compareValues(key, order = 'asc') {
return function innerSort(a, b) {
if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) return 0;
const comparison = a[key].localeCompare(b[key]);
return (
(order === 'desc') ? (comparison * -1) : comparison
);
};
}

You can read more about localeCompare over on MDN.

So there you have it — a short introduction to sorting an array of objects using vanilla JavaScript. Although many libraries offer this kind of dynamic sorting ability, as demonstrated, it’s not all that hard to implement this functionality yourself. Plus it’s good to understand what is going on under the hood.

◉ New features of JavaScript Arrays with ES2015

[1]. Array De-structuring

Traditional Method:

let animals =['Dog','Cat','Rat'];let a = animals[0];
let b = animals[1];
let c = animals[2];
console.log(a,b,c);

Now here we needed 3 statements just to assign 3 variables a, b & c. If we had like 10 variables, we would need 10 such statements. This approach definitely doesn’t scale efficiently. To cater to this problem, ES2015 introduced the concept to array DE-structuring. So instead of assigning each variable in a new line, we assign all local variables in single line of code within square brackets. For example:

We can reduce the number of lines even further by declaring the variables at the time of assignment itself.

let animals =['Dog','Cat','Rat'];
let [a,b,c] = animals;
console.log(a,b,c);
[a, ,b] = animals;
console.log(a,b); # Dog, Rat

So in the above example, we didn’t want to access the 2nd element of the array, so we left its placeholder in the array as blank and still got the correct values in variables a and b i.e. a = ‘Dog’ and b = ‘Rat’. ‘Cat’ was discarded.

Now, next time you need to swap two variables say a and b, do the following and you’ll be done in a single line.

[a, b] = [b, a];

[2]. iteration (for…of)

Enumerables vs Iterables

  • A pile of books is an enumerable
  • A row of books on a shelf is an iterable
  • JSON objects are enumerables
  • JSON arrays are iterables

Did you figure it the key quality? It’s order.

An iterable has an internal order to the pieces whereas

an enumerable has distinct parts, but they are unordered.

for…in vs for…of

Using ‘for…in’

let person = {
"first_name": "Jonathan",
"last_name": "Hsu",
"medium-handle": "@jhsu98"
}
for(const key in person) {
console.log(key + ": " + person[key]);
}
/*
"first_name: Jonathan"
"last_name: Hsu"
"medium-handle: @jhsu98"
*/

Using ‘for…of’

let scores = [43,58,28,69,38];for(const item of scores) {
console.log(item);
}
/*
43
58
28
69
38
*/

If we try to use for...of with an enumerable, expect the following error:

let person = {
"first_name": "Jonathan",
"last_name": "Hsu",
"medium-handle": "@jhsu98"
}
for(const item of person) {
console.log(item);
}
/*
"TypeError: person is not iterable
at gewuhimaza.js:6:84
at https://static.jsbin.com/js/prod/runner-4.1.7.min.js:1:13924
at https://static.jsbin.com/js/prod/runner-4.1.7.min.js:1:10866"
*/

I Thought Arrays Were Enumerables Too

let scores = [43,58,28,69,38];for(const item in scores) {
console.log(item);
}
/*
"0"
"1"
"2"
"3"
"4"
*/

Similar to how for...in counts over the identifiers of the object, for...in will count over the indexes — think of them as position identifiers.

[3]. Array.prototype.find()

let animals  = ['Dog', 'Cat', 'Rat'];let animal = animals.find(function(animal){
if(animal === 'Rat'){
return true;
}
});
console.log(animal); //Rat

[4]. Set

  • Set in ES6 are ordered: elements of the set is iterated in the same insertion order.
  • Set can store any types of values whether primitive or objects.
var set1 = new Set(["sumit","sumit","amit","anil","anish"]);
["sumit","amit","anil","anish"]
var set2 = new Set("fooooooood");
// 'f', 'o', 'd'
var set3 = new Set([10, 20, 30, 30, 40, 40]);
[10, 20, 30, 40]
// it is an empty set
var set4 = new Set();

[4]. Map (and not HOF map())

  • Map object can hold both objects and primitive values as either key or value.
  • When we iterate over the map object it returns the key, value pair in the same order as inserted.
var map1 = new Map([[1 , 2], [2 ,3 ] ,[4, 5]]);
console.log("Map1");
// 1 => 2
// 2 => 3
// 4 -> 5
var map2 = new Map([["firstname" ,"sumit"],["lastname", "ghosh"], ["website", "geeksforgeeks"]]);
console.log("Map2");
// firstname => sumit
// lastname => ghosh
// website => geeksforgeeks

◉ Weirdness of Arrays in JS (from techsith)

const arr = [1,2,3];
const arr[-1]= 4;
console.log(arr); #(3) [1, 2, 3, -1: 4]
console.log(length); # 3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~var arr1 = [];
arr1["index1"]= "anil";
arr1["index2"]= "kumar";
console.log(arr1); # [index1: "anil", index2: "kumar"]
console.log(arr1.length); # 0;
  • In JS, indexes are automatic .i.e. you cannot have an negative index, rather arrays are associative arrays underneath.
  • Objects don’t have a length property whereas Arrays do have a length property by default.
  • Objects take less execution time (on an average) for same no. of iterations as compared to array.

◉ Convert an Array to Object in JS:

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store