Sage-Code Laboratory
index<--

JavaScript Collections

Collections are groups of multiple values usually of the same type, identified by a key. The key must be a number or a string, while the value can be any data type: numeric, string or object. Collection pairs are ordered by key that are unique.

Page bookmarks

JavaScript Arrays

JavaScript arrays are ordered collection of multiple elements of same data type. An array holds all the elements under a single name. You can access each element by using its numeric index enclosed in square brackets. The index starts from [0] to [n-1] where n = total number of elements.

Example

 let numbers = [1,2,3,4,5,9,7,8,9,10]

array

Array Elements

Array Literals

An array literal is a list of values separated by comma and enclosed in square brackets like: numbers = [1,2,3...]. Element access notation is based on array name followed by index enclosed in square brackets like: numbers[x]. The array literal is a constant that is stored with the code similar to a string or a number.

Example:

//Let's create an array using array literal notation
var bike = ['road', 'mountain', 'cruiser'];

//update the third item in the array
bike[2] = 'hybrid';

//print the third item in the array
document.write(bike[2]); // hybrid

//Let's create an array using array constructor
var moreBikes = new Array(
 'road',
 'mountain',
 'cruiser');

//update the third item in the array
moreBikes[2] = 'hybrid';

//print the third item in the array
document.write(moreBikes[2]); // hybrid

In previous example an array is declared in two distinct ways.

  1. we can define an array using type inference from a literal.
  2. we can define an array using keyword "new" follow by the constructor "Array(…)".

Empty Array

To create an empty array: var fruits = []

Push()

To add elements into an array we can use array method push().

fruits.push("Banana");
fruits.push("Orange");
fruits.push("Apple");

Pop()

To remove last element from array we can use method pop();

class="lang:js decode:true">fruits.pop(); // => Apple
// fruits = ["Banana", "Orange"]

Shift()

To remove first element from array we can use method shift();

fruits.shift(); // => "Banana"
// fruits = ["Orange"]

Unshift()

To add element as first element in array we can use method unshift();

fruits.unshift("Mango");
// fruits = ["Mango", "Orange"]

Slice()

The slice(first, last) method slices out a piece of an array into a new array but the old array remain unchanged. To change the old array we use splice() method.

var fruits = ["Banana", "Orange", "Lemon", "Apple"];
var citrus = fruits.slice(1, 3);
console.log(citrus) // citrus = ["Orange", "Lemon"]
console.log(fruits) // citrus = ["Banana", "Orange", "Lemon", "Apple"]

array

Slice an Array

Splice()

The method splice(start_position, how_many) is removing elements from array.

fruits = ["Banana", "Orange", "Lemon", "Apple"];
citrus = fruits.splice(1, 2);
console.log(citrus)// citrus =  ["Orange", "Lemon"]
console.log(fruits)// fruits =  ["Banana", "Apple"];

array

Splice an Array

Note: Splice() method can be used to insert elements into array using a third parameter.

splice(start_position, how_many, new_elements)

var fruits = ["Banana", "Orange", "Lemon", "Apple"];
fruits.splice(2, 0, "Mango");
// fruits =  ["Banana", "Orange", "Mango", "Lemon", "Apple"]

More functions:

For details about all array functions check external Mozilla documentation:

Method Description
concat() Joins two or more arrays, and returns a copy of the joined arrays
copyWithin() Copies array elements within the array, to and from specified positions
entries() Returns a key/value pair Array Iteration Object
every() Checks if every element in an array pass a test
fill() Fill the elements in an array with a static value
filter() Creates a new array with every element in an array that pass a test
find() Returns the value of the first element in an array that pass a test
findIndex() Returns the index of the first element in an array that pass a test
forEach() Calls a function for each array element
from() Creates an array from an object
includes() Check if an array contains the specified element
indexOf() Search the array for an element and returns its position
isArray() Checks whether an object is an array
join() Joins all elements of an array into a string
keys() Returns a Array Iteration Object, containing the keys of the original array
lastIndexOf() Search the array for an element, starting at the end, and returns its position
map() Creates a new array with the result of calling a function for each array element
pop() Removes the last element of an array, and returns that element
push() Adds new elements to the end of an array, and returns the new length
reduce() Reduce the values of an array to a single value (going left-to-right)
reduceRight() Reduce the values of an array to a single value (going right-to-left)
reverse() Reverses the order of the elements in an array
shift() Removes the first element of an array, and returns that element
slice() Selects a part of an array, and returns the new array
some() Checks if any of the elements in an array pass a test
sort() Sorts the elements of an array
splice() Adds/Removes elements from an array
toString() Converts an array to a string, and returns the result
unshift() Adds new elements to the beginning of an array, and returns the new length
valueOf() Returns the primitive value of an array

Note:  In future examples we will use some of these functions.

Using console

You can use JavaScript console for debugging purposes.

Example:

var bike = ['road', 'mountain', 'cruiser'];
var test = bike.shift();
console.log(test)
console.log(bike)

Output:

"road"
(2) ["mountain" ,"cruiser"]

Destructuring

The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables, using array like notation [...]. In next example you can see the syntax used to define two variables and assign first two values from array. This is how destructuring array works: "by position".

Example:

/* define array for test */
let a = [1, 2, 3, 4, 5];

/* define new variables y, z */
let [x, y] = a; // destructuring assignment

console.log(x); // 1
console.log(y); // 2

Note: You will learn more about destructuring after you learn about objects.

Example: swap

Swapping two values with destructuring syntax:

let a = 1, b = 3;
[a, b] = [b, a]; //swap

console.log("a = " + a);  // 3
console.log("b = " + b);  // 1

Example: skip

You can skip one or more values by using multiple comas without any variable, or by using anonymous variable "_" that is by convention not used for anything. So you can reuse same variable for missing values.

/* define array for test */
let a = [1, 2, 3, 4, 5];

/* define new variables x, y, z */
let [x, y,,,z] = a; // ignore two elements

/* expected results */
console.log(x); // 1
console.log(y); // 2
console.log(z); // 5

/* define new variables h, o */
let [h,_,o] = a; // ignore last elements

/* expected results */
console.log(h); // 1
console.log(o); // 3


Note: You can do more with destructuring:  MDN Destructuring


Array as object

JavaScript is difficult to understand when you migrate from C because its behavior is strange. An array is not an enumeration of elements ordered by "index", in fact is a disguised "associative array" with keys starting from "0" to the maximum number of elements minus one. However you can remove elements from an array and the index will have gaps if you do this. You can even remove the first element and the array will not start with array[0]. This is because "associative array" is a generic structure used in JavaScript for all objects.

Don’t believe me? Try this:

const array = [1,2,3];
console.log(typeof(array)); // object

Note:  The type ‘array’ do not exist in JavaScript. You have in fact declared an object here.

Associative arrays

To create a customized associative array in JavaScript we use JSON. An associative array is an object similar to an array. It has keys and values associated with the keys. Each key is unique and can be integer or a string.

Example:

/* associative array */
var array = { 1:4, 2:5, 3:6 };
// read array values
for (x in array) {
 console.log(`array[${x}]= ${array[x]}`);
}

Output:

array[1]= 4
array[2]= 5
array[3]= 6

Modify Associative Array

You can add new elements in associative array using notation: array[key] = value. If the key do not exist a new element will be created automatically. To remove an element you can use "delete" statement.

Example:

/* associative array */
var array = { 1:4, 2:5, 3:6 };
// add a new element in array
array[4] = 7;
// remove an element from array
delete array[1];
console.log(array);

Output:

{2: 5 , 3: 6 , 4: 7}

String keys

Instead of numbers you can use string keys. These keys can have same convention as variables. If you follow same convention, the elements of the associative array can be accessed with dot notation:

Example:

/* associative array */
let array = { "first":1, "second":2, "third":3 };
// access element value using object notation
let max = array.first; // 1
// access element value using [key] notation
if (max < array["second"])
 max = array["second"]; // 2
if (max < array["third"])
 max = array["third"]; // 3
console.log(max); //expect: 3

Object methods

The Object is the fundamental class for all objects in JavaScript, therefore also "associative array" is responding to Object methods. In the next examples I show you how to use some methods but you can look into reference manual and figure out the rest:

Example:

Reading [keys, value] entries:

/* associative array */
var array = { 1:4, 2:5, 3:6 };
// read array values
for (element of Object.entries(array)) {
 console.log(element);
}

Output:

["1" ,4]
["2" ,5]
["3" ,6]

Example:

Reading [key,value] pairs using for…of loop:

/* associative array */
var array = { 1:4, 2:5, 3:6 };
// deconstruct pairs
for ([key,value] of Object.entries(array)) {
 console.log(key + "->" + value);
}

Output:

1->4
2->5
3->6

Example:

Reading keys and values in separated arrays:

/* associative array */
const array = { "first":1, "second":2, "third":3 };
// using Object functions:
console.log(Object.keys(array));
console.log(Object.values(array));

Output:

["first" ,"second" ,"third"]
[1 ,2 ,3]

The set collection

A mathematical set is a collection of unique items. JavaScript Set is a collection of key-value pairs where key === value and key is unique. You can convert an array into a Set and then duplicates are eliminated.

Example:

// array fixture
var array = [ 4, 5, 5, 6, 6];
// convert to set
var myset = new Set(array);
// elements of set are unique
for (element of myset) {
 console.log(element);
}
// convert back to array
var a = Array.from(myset)
console.log(a); // [4,5,6]

Set methods

You can create an empty Set then you can use methods to append data values to the set. If you attempt to append same value twice, only one will be stored in the Set. Of course you can verify if one value is in the set and you can remove values from the set.

/* empty Set */
let mySet = new Set();
/* add some elements */
mySet.add(1); // Set [1]
mySet.add(2); // Set [1, 2]
mySet.add(2); // Set [1, 2]
mySet.add(3); // Set [1, 2, 3]
console.log([...mySet]); // [1,2,3]
console.log('size='+mySet.size); // 3
/* remove one element */
mySet.delete(3);
console.log(mySet.has(3)) // false
console.log('size='+mySet.size); // 2
console.log([...mySet]); // [1,2]

Note: There is a keyword: "set" that has nothing to do with "Set". This is an unfortunate coincidence in English. Lowercase "set" is a "setter" method and not a collection. Do not confuse the two and do not give name "set" to a "Set".

Map object

The Map object holds key-value pairs very similar to an object. Any value (both objects and primitive values) may be used as either a key or a value. That was not possible with a normal object. A map may perform better than object in scenarios involving frequent addition and removal of key pairs.

Example:

// create a Map
var map = new Map(
 [
 ["a", 1],
 ["b", 2],
 ["c", 3]
 ]);
// elements of map are unique
for ([key, value] of map) {
 console.log("key = "+ key + ", value = "+ value);
}
// convert back to array
console.log(Array.from(map));

Map methods

Map methods are very similar to Set methods. Two methods are a little bit off. "set" and "get" methods, that are also keywords. So JavaScript can do this (unfortunately) it is overwriting keyword meaning with methods. Do not be mad, get used to JavaScript to break the rules from time to time. Hell it is a free language, so you can’t complain about it.

Example:

// create empty Map object
let myMap = new Map();
// prepare 3 keys
let keyString = 'a string'
let keyObj = {}
let keyFunc = function() {};
let keyArray = [1,2];
// setting the values
myMap.set(keyString, "key is a string");
myMap.set(keyObj, "key is object");
myMap.set(keyFunc, "key is a function");
myMap.set(keyArray, "key is a array");
// reading size of the map
console.log("Map size = " + myMap.size); // 4
// getting the values
console.log(myMap.get(keyString) );
console.log(myMap.get(keyObj) );
console.log(myMap.get(keyFunc) );
console.log(myMap.get(keyArray) );

Note:  By now you already know that JavaScript is using objects for everything. Map is also an object. When you define a new map you actually inherit methods from Map.prototype. So this is what you need to look for to find all Map methods.

References:

Spread Operator:"..."

Spread syntax allows an iterable such as an array expression or strings to be expanded. It can be used in places where zero or more arguments or elements are expected, Also can be used to expand objects in places where key-value pairs are expected.

Example:

// expect 3 arguments
function sum(x, y, z) {
 return x + y + z;
}
// spread array elements by position
const numbers = [1, 2, 3];
const result = sum(...numbers);
console.log(result) // expected output: 6

Spreading Arrays:

You can do other interesting stuff by using spread operator with arrays:

/* clone arrays */
var array = [1, 2, 3]; // fixture
var clone = [...array]; // spread elements
// test different arrays
clone[3] = 4;
console.log(clone); // [1, 2, 3, 4]
console.log(array); // [1, 2, 3]
/* concatenate arrays */
merge = [0, ...array, ...clone]
console.log(merge); // [0,1,2,3,1,2,3,4]

Spreading Object:

Spreading operator "..." can be used in object literals. This enable you to combine elements from objects or send properties of an object as parameters for a function.

// define two objects
let obj1 = { foo: 'foo', x: 42 };
let obj2 = { foo: 'bar', y: 13 };
// clone all attributes of object
let clonedObj = { ...obj1 };
console.log(clonedObj) // Object { foo: "bar", x: 42 }
// on merge, properties can not be duplicate
let mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj) // Object { foo: "foo", x: 42, y: 13 }

Variable arguments:

It is possible to define functions with variable number of arguments. To call these functions you can use a larger or smaller list of arguments separated by comma. In next example we use spreading operator "..." to feed a function that receive variable number of arguments:

Example:

// calculate median number (average)
function avg (...args) {
   let sum = 0;
   for (let n of args) {
   sum += n;
 }
 return sum/args.length;
}
// fixture (test data)
let data = [0,1,2,3,4,5,6,7,8,9,10];
// normal call (we can not use fixture)
let test = avg(0,1,2,3,4,5,6,7,8,9,10);
// call using spread operator and fixture:
let median = avg(...data); //spreading an array
// check if the test is successful
console.log(median == test); //expect true

Rest syntax

Rest syntax is the opposite of spread syntax: the "spread" expands an array into its elements, while the "rest" collects multiple elements and condenses them into a single element. The rest operator is the same as spread operator: "...", so it may be difficult to grasp.

Example:

// rest arguments
function test(a, b, ...more) {
   console.log("a = " + a);
   console.log("b = " + b);
   console.log(more);
}
// call function: a=1, b=2, more = [3, 4, 5]
test(1,2,3,4,5);
// call function: a="x", b="y", more = ["z"]
test("x","y","z");

Note: Operator "…" is used in C for same purpose. It is called sometimes "varargs" or "variable arguments". A function can be designed to receive as the last argument the "rest of arguments".

Example:

The rest syntax can be used in combination with decomposition assignment. Collecting the rest of elements can be done into target array or object. The two are very different. You should remember we have done this before when we have learned about objects:

// collect rest of elements
let [x,...rest] = [1,2,3,4,5];
console.log(rest); // [3,4,5];
// collect rest of attributes
let {a,...test} = {a: 1, b: 2, c: 3};
console.log(test); // {b: 2, c: 3};

Read next: Errors