JavaScript - collections

revision:


Content

"indexed collection" is a collection of data which is listed by their index. "keyed collections" are collections of data represented in the key-value notation JavaScript HTML DOM collections


"indexed collection" is a collection of data which is listed by their index.

top

JavaScript collection indices are 0-based, which means they start at 0, not 1 and go up to n-1, n being the number of objects in the collection.
JavaScript has two kinds of indexed collections Arrays and TypedArrays.

Array object in JavaScript is an "ordered list", whose elements can be accessed using indices.

1/ Creating an array : there are multiple ways of creating an array object in JavaScript, and there's not much difference under the hood:

        let myArray1 = [x1, x2, ... , xN];
        let myArray2 = new Array(x1, x2, ... , xN);
        let myArray3 = Array(x1, x2, ... , xN);
    

To create an array with non-zero length, but without any items, either of the following can be used:

        var arr = new Array(arrayLength);
        var arr = Array(arrayLength);
        // This has exactly the same effect
        var arr = []; 
        arr.length = arrayLength;
    

In the above code, arrayLength must be a Number. Otherwise, an array with a single element (the provided value) will be created

Arrays can also be assigned as a property of a new or an existing object:

        var obj = {};
        // ...
        obj.prop = [element0, element1, ..., elementN];
        // OR
        var obj = {prop: [element0, element1, ...., elementN]}
    

2/ In JavaScript arrays are not type-based, which means that you don't have to define the type of the array beforehand and you don't have to add only homogeneous elements

let myArray = ["one", 1, "two", 2]; is valid syntax and the array stores strings and integers.

3/ Each array has a length property, which is determined at the same time the array is initialized. When the array is created, a value is assigned to its length property. Changing the length will change the array.

examples: array length

code:
                    <;div>
                        <;p id="arr-A"><;/p>
                        <;p id="arr-B"><;/p>
                        <;p id="arr-C"><;/p>
                        <;p id="arr-D"><;/p>
                        <;p id="arr-E"><;/p>
                        <;p id="arr-F"><;/p>
            
                    <;/div>
                    <;script>
                        let myArray = ["one", 1, "two", 2];
                        document.getElementById('arr-A').innerHTML = "array: " + myArray;
                        document.getElementById('arr-B').innerHTML = "array length: " + myArray.length;
                        myArray.length = 5;
                        document.getElementById('arr-C').innerHTML = "array: " + myArray;
                        document.getElementById('arr-D').innerHTML = "array length: " + myArray.length;
                        myArray.length = 1;
                        document.getElementById('arr-E').innerHTML = "array: " + myArray;
                        document.getElementById('arr-F').innerHTML = "array length: " + myArray.length;
                    <;/script>
                

4/ There are also three ways to create empty arrays with allocated memory.

examples: create empty arrays



code:
                    <;div>
                        <;div id="arr-G"><;/div><;br>
                        <;div id="arr-H"><;/div><;br>
                        <;div id="arr-I"><;/div><;br>
                    <;/div>
                    <;script>
                        let myArray1 = new Array(4); // creates an array with 4 empty spaces
                        document.getElementById('arr-G').innerHTML = "array: " + myArray1.length;
                        let myArray2 = Array(4); // similar to the previous one, just without the keyword new
                        document.getElementById('arr-H').innerHTML = "array: " + myArray2.length; 
                        let myArray3 = [];
                        myArray3.length = 4 // this one is a bit different, we assign the value to the property length
                        document.getElementById('arr-I').innerHTML = "array: " + myArray3.length; 
                    <;/script>
                

Adding elements to an array is done by accessing the elements through indexes and assigning them a value

examples: access array through indices


code:
                    <;div>
                        <;div id="arr-J"><;/div><;br>
                        <;div id="arr-K"><;/div><;br>
                    <;/div>
                    <;script>
                        let myArray_A = new Array(4); 
                        myArray_A[0] = "one"
                        myArray_A[1] = "two"
                        myArray_A[2] = "three"
                        myArray_A[3] = "four"
                        console.log(myArray)
                        document.getElementById('arr-J').innerHTML = "array: " + myArray_A;
                        // more elements can be added to the array
                        myArray_A[4] = "five"
                        myArray_A[5] = "six"
                        document.getElementById('arr-K').innerHTML = "array: " + myArray_A;
                    <;/script>
                

Iterating through an array can be done using a for loop or a forEach loop.

examples: iterating through an array.


code:
                    <;div>
                        <;div id="arr-L"><;/div><;br>
                        <;div id="arr-M"><;/div><;br>
                    <;/div>
                    <;script>
                        let myArray_B = new Array(6);
                        myArray_B[0] = "one"
                        myArray_B[1] = "two"
                        myArray_B[2] = "three"
                        myArray_B[3] = "four"
                        myArray_B[4] = "five"
                        myArray_B[5] = "six"
                        for(let i = 0; i <; myArray_B.length; i++){
                            document.getElementById('arr-L').innerHTML += myArray_B[i] + " , ";
                        }
                        myArray_B.forEach( function(element){document.getElementById('arr-M').innerHTML += (element) + " , ";});
                    <;/script>
                

TypedArray objects come into play when working with raw binary data

JavaScript typed arrays are divided into buffers and views.

A buffer is an object only storing a chunk of data, with no methods to access or manipulate that data. In order to achieve that, you must use a view, which provides a context, a data type that turns data into a TypedArray.
A buffer is implemented through an ArrayBuffer object. It is used to represent a fixed-length binary data buffer.
To represent this buffer, we have to create a view - dataView - which represents that buffer in a chosen format. There are various types of views, representing the most common numeric types:

Int8Array - value range [-128, 127];
UInt8Array - value range [0, 255], u stands for unsigned;
Int16Array - value range [-32768, 32767];
UInt16Array - value range [0, 65535];
Float32Array - value range [1.2E-38, 3.4E38]

examples: buffers and views


code:
                    <div>
                        <div id="arr-N"></div><br>
                        <div id="arr-O"></div><br>
                    </div>
                    <script>
                        let tArray = new Int8Array(8);
                        tArray[0] = 10; 
                        console.log(tArray);
                        document.getElementById("arr-N").innerHTML = "Int8Array: " + tArray;
                        let tArray1 = new Int8Array(8);
                        tArray1[5] = 10; 
                        console.log(tArray1);
                        document.getElementById("arr-O").innerHTML = "Int8Array: " + tArray1;
                    </script>
                </pre>
            


"keyed collections" are collections of data represented in the key-value notation

top

Elements' values are accessed and manipulated through their respective keys.

In JavaScript, there are two types of keyed collections: Map and Set.

Both Maps and Sets in JavaScript can have a single value attributed to a single key, though you could hack it by attributing a List as a value, containing multiple elements. It's still worth noting that the List itself is the value - not its constituent elements.
Additionally, keys have to be unique.

The Map object is a standard map containing key-value pairs.

1/ To create a new Map object, we simply call the constructor: let myMap = new Map();

2/ Adding an element to a Map: elements can be added to the Map via the set() method, which accepts a key_name which has to be a String, and a value which can be of any type.

        myMap.set('key1', 'value1')
        myMap.set('key2', 'value2')
        myMap.set('key3', 'value3')
    
examples: add elements to a map object.

code:
                    <div>
                        <div id="arr-P"></div><br>
                    </div>
                    <script>
                        let myMap = new Map();
                        myMap.set("one", 1);
                        myMap.set("two", 2);
                        myMap.set("three", "three");
                        console.log(myMap);
                        document.getElementById("arr-P").innerText = myMap;
                    </script>
                

Maps are also heterogeneous, so you don't have to have the same value type for all keys: Map { 'one' => 1, 'two' => 2, 'three' => 'three' }

3/ To access elements of a Map, we simply get() them, passing in the the key_name as these are the unique identifiers in the Map.

examples: access elements of a map.



code:
                    <div>
                        <div id="arr-Q"></div><br>
                        <div id="arr-R"></div><br>
                        <div id="arr-S"></div><br>
            
                    </div>
                    <script>
                        let myMap1 = new Map();
                        myMap1.set("one", 1);
                        myMap1.set("two", 2);
                        myMap1.set("three", "three");
                        console.log(myMap.get("two"));
                        document.getElementById("arr-Q").innerText = myMap.get("two");
                        document.getElementById("arr-R").innerText = myMap.get("one");
                        document.getElementById("arr-S").innerText = myMap.get("three");
                    </script>
                

Since this collection is not index based, we cannot access some value using square brackets: myMap["two"] will return an undefined value. However, if we call the get(key_name) method on the non-existing key, the return value will be undefined too.

4/ Map methods:

forEach() : can easily be used to iterate and perform operations on all the entries.

        myMap.forEach(function(value, key){
            consoloe.log(key + '-.'+value);
        });    
        // key1 -> value1
        // key2 -> value2
    

set(key_name, value) : adds a key-value pair to the Map.

myMap.set('key1', 'value1');
myMap.set('key7', 'value7');

get(key_name) : returns the value assigned to the passed key, if there is no such key - returns undefined.

console.log(myMap.get('key1'));
console.log(myMap.get('key7'));

has(key_name) : returns true or false depending on whether a Map has a key key_name or not.

console.log(myMap.has('key1'));
console.log(myMap.has('key7'));

delete(key_name) : deletes both the key and the value according to the passed key_name, if a non-existing key is passed - nothing happens.

myMap.delete('key1');
myMap.delete('key7');

clear() : deletes every key-value pair from the Map object.

myMap.clear();

5/ Map properties:

size property : contains a number value representing the size of a Map object.

console.log(myMap.size);

6/ The WeakMap object is a collection of key-value pairs, where keys are objects only and values can be of various types. The name weak comes from the activity where these objects are a target of garbage collection - which means that if there are no references to it, it will be removed. The API for WeakMap is the same as Map's API, without any iteration methods as WeakMaps are not iterable.

The Set object is a collection of values only

1/ These values are unique, which means there are no duplicates allowed and trying to add a duplicate element simply won't add anything. Printing sets prints their elements in insertion order, and adding a duplicate element at the start and end will only result in the first one being present.

2/ Creating a Set is as simple as calling its constructor: let mySet = new Set();

3/ Adding an element to a Set: to add a new element to a set, we use the add(value) method.Sets can contain arbitrary values.

        mySet.add(1);
        mySet.add(5);
        mySet.add(10);
        mySet.add(10);          // will be deleted because it already exist
        mySet.add(undefined);   
        mySet.add(NaN);
        mySet.add('some text');
        mySet.add({a: 1, b: 2});
        mySet.add([1, 2, 3]);
    
examples: add elements to a Set

code:
                    <div>
                        <div id="arr-T"></div><br>
                    </div>
                    <script>
                        let mySet = new Set();
                        mySet.add('one');
                        mySet.add('two');
                        mySet.add('three');
                        mySet.add('two');
                        mySet.add('1');
                        console.log(mySet);
                        document.getElementById("arr-T").innerText = JSON.stringify(mySet);
                    </script>
                

4/ Set methods:

add(value) : adds a new value to the Set object;

mySet.add(121);

delete(value) : deletes the passed value from the Set object

mySet.delete(2);

has(value) : returns true or false depending on whether the value is in the Set object

console.log(mySet.has(10));
console.log(mySet.has(200);

clear() : deletes all the values from the Set object

mySet.clear();
examples: Set methods



code:
                    <div>
                        <div id="arr-U"></div><br>
                        <div id="arr-V"></div><br>
                        <div id="arr-W"></div><br>
                    </div>
                    <script>
                        let mySet1 = new Set();
                        mySet1.add(1);
                        mySet1.add('two');
                        mySet1.add('three');
                        mySet1.delete('two');
                        console.log(mySet1);
                        document.getElementById("arr-U").innerText = mySet1.has(1);
                        document.getElementById("arr-V").innerText = mySet1.has('two');
                        mySet1.clear();
                        document.getElementById("arr-W").innerText = mySet1.has('1');
                    </script>
                

5/ Set properties

size property :contains a number value representing the size of a Set object.

console.log(mySet.size);  

6/ A WeakSet object is a collection of object, which have to be unique. This refers to the objects in memory, not their fields or values.

There are some key differences between a Set and a WeakSet:

WeakSet is a collection of objects, whereas a Set is a collection of values of any type.
If there is no reference to the WeakSet object, it is deleted.


JavaScript HTML DOM collections

top

This type of collection is front-end web development related.

When working on a web page, we can access all the elements on the page thanks to the DOM tree. So, when accessing multiple elements at once, they are being returned as an HTMLCollection - an array-like collection of HTML elements.

If we have a web page containing multiple <p> tags, we can retrieve them with document.getElementsByTagName("p"), which returns a collection of all the <p> elements on the page.

A HTMLCollection is an "indexed" collection, since we're accessing an element from it using an index value. It's not a true indexed JavaScript collection since it's not an array, because it doesn't have the array methods, but index accessing is available.

An HTMLCollection has the length property, which returns its size. i.e. the number of elements in an HTMLCollection.

examples: HTMLCollection

Hello world!

Hello Belgium!

Click the button to change the color of all 'DOM-A" class elements.

code:
                    <div>
                        <p class="DOM-A">Hello world!</p>
                        <p class="DOM-A">Hello Belgium!</p>
                        <p id="DOM-3"></p>
                        <p id="DOM-4"></p>
                        <p>Click the button to change the color of all 'DOM-A" class elements.</p>
                        <button onclick="changeColor()">try it</button>
                    </div>
                    <script>
                        const myCollection = document.getElementsByClassName("DOM-A");
                        document.getElementById("DOM-3").innerHTML = "The innerHTML of the second paragraph is: " + 
                        myCollection[1].innerHTML;
                        document.getElementById("DOM-4").innerHTML = "This example contains " + myCollection.length + 
                        " paragraphs.";
                        function changeColor() {
                            const myCollection = document.getElementsByClassName("DOM-A");
                            for (let i = 0; i < myCollection.length; i++) {
                                myCollection[i].style.color = "red";
                            }
                        }
                    </script>