Image for post
Image for post

📄 Table of Contents

  • How an array in JS is different from array in other languages.
  • check if variable is an Array ( & not Object).
  • Sort an array, array of objects, etc.
  • New Array features supported in ES2015.
  • weirdness of Arrays in JS
  • Array to Object in JS ([] => {})

An array in JavaScript can hold different elements of different types…unlike arrays in other programming 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?

3 ways using isArray(), instanceOf operator and constructor property.

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()

When checking for Array instance, Array.isArray is preferred over instanceof because it works through iframes.

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

By default, the JavaScript Array.sort function converts each element in the array that needs to be sorted into a string, and compares them in Unicode code point order.

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

Let’s say that foo and bar are the two elements being compared by the compare function, and the return value of the compare function is set up as follows:

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

Now let’s look at sorting an array of objects. For this demo we’ll use an array of singers:

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

Let’s finish up by making this more dynamic. Let’s create a sorting function, which you can use to sort an array of objects, whose values are either strings or numbers. This function has two parameters — the key we want to sort by and the order of the results (i.e. ascending or descending):

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()

In our example above, we want to be able to sort an array of objects, whose values are either strings or numbers. If, however, you know that you’ll only be dealing with objects whose values are strings, you can tidy up the code a little using JavaScript’s localeCompare method.

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

source: https://medium.com/better-programming/what-is-the-difference-between-for-in-and-for-of-in-javascript-650952654e97

[1]. Array Destructuring

Array destructuring allows us to assign values to variables from an array using syntax similar to the array itself. Let’s look at the code below where we have an array of animals. We need to assign variables a, b & c to first three elements of the array.

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)

Image for post
Image for post

Enumerables vs Iterables

I like to think of iterables as a square and enumerables as a rectangle. Consequently, all iterables are enumerables; however, not all enumerables are 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’

We begin with for...in, which is used to loop over an enumerable. This is perfect for counting over key-value pairs in an object, such as the example below.

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’

OK, now we transition to the for...of loop. This loop has a very similar syntax. However, an iterable is required after the of keyword — in contrast to the requirement of an enumerable with in.

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

You’re right! We saw that passing an enumerable to for...of will cause an error, but passing an iterable to for...in is accepted.

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()

With ES2015, JavaScript introduced a new higher order function to be used on JavaScript arrays. This function is Array.prototype.find(). This function returns the element which satisfies a given condition. It takes as an argument a callback function which returns a boolean value (true or false). The callback function is executed against each element in the array until callback returns true for an element or when callback function has been executed for all element in the array.

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

[4]. Set

• A set is a collection of items which are unique i.e no element is repeated.

  • 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 is a collection of elements where each element is stored as a Key, value pair.
  • 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
Image for post
Image for post

◉ 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";
arr2["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.

Array.fill()

Image for post
Image for post

Array.from()

Image for post
Image for post

Array.find()

Image for post
Image for post

Array.findIndex()

Image for post
Image for post

Array.of()

Image for post
Image for post

Convert an Array to Object in JS:

Image for post
Image for post

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