12. Arrays and Collections

Arrays

Creating Arrays

// Array literal
const fruits = ["apple", "banana", "orange"];

// Constructor
const numbers = new Array(1, 2, 3, 4, 5);

// Array.of() (ES6+)
const mixed = Array.of(1, "hello", true);

// Array.from() (ES6+)
const range = Array.from({ length: 5 }, (_, i) => i + 1); // [1, 2, 3, 4, 5]
const stringArray = Array.from("hello"); // ["h", "e", "l", "l", "o"]

Accessing Elements

const fruits = ["apple", "banana", "orange"];

console.log(fruits[0]);     // "apple"
console.log(fruits[2]);     // "orange"
console.log(fruits.length); // 3

// Last element
console.log(fruits[fruits.length - 1]); // "orange"

Modifying Arrays

const fruits = ["apple", "banana"];

// Add to end
fruits.push("orange");
console.log(fruits); // ["apple", "banana", "orange"]

// Add to beginning
fruits.unshift("grape");
console.log(fruits); // ["grape", "apple", "banana", "orange"]

// Remove from end
const last = fruits.pop();
console.log(last);  // "orange"
console.log(fruits); // ["grape", "apple", "banana"]

// Remove from beginning
const first = fruits.shift();
console.log(first); // "grape"
console.log(fruits); // ["apple", "banana"]

Array Methods

Iteration Methods

const numbers = [1, 2, 3, 4, 5];

// forEach
numbers.forEach(num => console.log(num)); // 1 2 3 4 5

// map
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// filter
const even = numbers.filter(num => num % 2 === 0);
console.log(even); // [2, 4]

// reduce
const sum = numbers.reduce((total, num) => total + num, 0);
console.log(sum); // 15

// find
const found = numbers.find(num => num > 3);
console.log(found); // 4

// findIndex
const index = numbers.findIndex(num => num > 3);
console.log(index); // 3

// some
const hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven); // true

// every
const allEven = numbers.every(num => num % 2 === 0);
console.log(allEven); // false

Manipulation Methods

let fruits = ["apple", "banana", "orange"];

// slice (creates new array)
const citrus = fruits.slice(1, 3);
console.log(citrus); // ["banana", "orange"]

// splice (modifies original array)
fruits.splice(1, 1, "grape", "kiwi");
console.log(fruits); // ["apple", "grape", "kiwi", "orange"]

// concat
const moreFruits = fruits.concat(["pear", "plum"]);
console.log(moreFruits); // ["apple", "grape", "kiwi", "orange", "pear", "plum"]

// join
const fruitString = fruits.join(", ");
console.log(fruitString); // "apple, grape, kiwi, orange"

// reverse (modifies original)
fruits.reverse();
console.log(fruits); // ["orange", "kiwi", "grape", "apple"]

// sort (modifies original)
fruits.sort();
console.log(fruits); // ["apple", "grape", "kiwi", "orange"]

ES6+ Methods

const numbers = [1, 2, 3, 4, 5];

// includes
console.log(numbers.includes(3)); // true
console.log(numbers.includes(6)); // false

// flat
const nested = [1, [2, [3, [4]]]];
console.log(nested.flat());     // [1, 2, [3, [4]]]
console.log(nested.flat(2));    // [1, 2, 3, [4]]
console.log(nested.flat(Infinity)); // [1, 2, 3, 4]

// flatMap
const sentences = ["Hello world", "How are you"];
const words = sentences.flatMap(sentence => sentence.split(" "));
console.log(words); // ["Hello", "world", "How", "are", "you"]

Typed Arrays

// Int32Array
const intArray = new Int32Array(4);
intArray[0] = 42;
console.log(intArray); // Int32Array [42, 0, 0, 0]

// Float64Array
const floatArray = new Float64Array([1.1, 2.2, 3.3]);
console.log(floatArray); // Float64Array [1.1, 2.2, 3.3]

// Uint8ClampedArray (for image data)
const imageData = new Uint8ClampedArray([0, 255, 128]);
console.log(imageData); // Uint8ClampedArray [0, 255, 128]

Float16 and Resizable Buffers (ES2024–ES2025)

// Float16Array (ES2025)
const f16 = new Float16Array(4);
f16[0] = 1.5;
console.log(f16.length); // 4

// DataView getFloat16/setFloat16 (ES2025)
const buf = new ArrayBuffer(4);
const dv = new DataView(buf);
dv.setFloat16(0, 1.5);
console.log(dv.getFloat16(0)); // 1.5

// Math.f16round (ES2025)
console.log(Math.f16round(0.33333));

// Resizable ArrayBuffer (ES2024)
const rab = new ArrayBuffer(8, { maxByteLength: 16 });
console.log(rab.byteLength); // 8
rab.resize(12);
console.log(rab.byteLength); // 12

// ArrayBuffer transfer (ES2024)
const moved = rab.transfer(); // detaches rab and moves contents

Maps (ES6+)

// Creating a Map
const userRoles = new Map();

// Setting values
userRoles.set("john", "admin");
userRoles.set("jane", "user");
userRoles.set("bob", "moderator");

console.log(userRoles.get("john")); // "admin"
console.log(userRoles.has("jane")); // true
console.log(userRoles.size);        // 3

// Iterating
for (const [user, role] of userRoles) {
    console.log(`${user}: ${role}`);
}

// Keys, values, entries
console.log([...userRoles.keys()]);   // ["john", "jane", "bob"]
console.log([...userRoles.values()]); // ["admin", "user", "moderator"]
console.log([...userRoles.entries()]); // [["john", "admin"], ["jane", "user"], ["bob", "moderator"]]

// Delete and clear
userRoles.delete("bob");
console.log(userRoles.size); // 2
userRoles.clear();
console.log(userRoles.size); // 0

Sets (ES6+)

// Creating a Set
const uniqueNumbers = new Set([1, 2, 2, 3, 3, 3]);
console.log(uniqueNumbers); // Set {1, 2, 3}

uniqueNumbers.add(4);
uniqueNumbers.add(2); // Duplicate, ignored
console.log(uniqueNumbers.has(4)); // true
console.log(uniqueNumbers.size);   // 4

// Iterating
for (const num of uniqueNumbers) {
    console.log(num);
}

// Convert to array
const arrayFromSet = [...uniqueNumbers];
console.log(arrayFromSet); // [1, 2, 3, 4]

// Set operations
const setA = new Set([1, 2, 3, 4]);
const setB = new Set([3, 4, 5, 6]);

const union = new Set([...setA, ...setB]);
const intersection = new Set([...setA].filter(x => setB.has(x)));
const difference = new Set([...setA].filter(x => !setB.has(x)));

console.log(union);        // Set {1, 2, 3, 4, 5, 6}
console.log(intersection); // Set {3, 4}
console.log(difference);   // Set {1, 2}

New Set methods (ES2025)

const A = new Set([1, 2, 3, 4]);
const B = new Set([3, 4, 5]);

console.log(A.union(B));               // Set {1, 2, 3, 4, 5}
console.log(A.intersection(B));        // Set {3, 4}
console.log(A.difference(B));          // Set {1, 2}
console.log(A.symmetricDifference(B)); // Set {1, 2, 5}

console.log(A.isSubsetOf(A.union(B)));     // true
console.log(A.isSupersetOf(new Set([2]))); // true
console.log(new Set([1]).isDisjointFrom(B)); // true

Array Grouping (ES2024)

const nums = [1, 2, 3, 4, 5];

// Group into object by key
const byParity = nums.group(n => (n % 2 ? 'odd' : 'even'));
// { odd: [1, 3, 5], even: [2, 4] }

// Group into Map by key
const byParityMap = nums.groupToMap(n => (n % 2 ? 'odd' : 'even'));
// Map(2) { 'odd' => [1, 3, 5], 'even' => [2, 4] }

WeakMap and WeakSet

// WeakMap
let obj1 = { name: "John" };
let obj2 = { name: "Jane" };

const weakMap = new WeakMap();
weakMap.set(obj1, "admin");
weakMap.set(obj2, "user");

console.log(weakMap.get(obj1)); // "admin"

// Objects can be garbage collected
obj1 = null; // obj1 can now be garbage collected

// WeakSet
const weakSet = new WeakSet();
let obj = { name: "test" };
weakSet.add(obj);

console.log(weakSet.has(obj)); // true
obj = null; // Can be garbage collected

Next Steps

Arrays and collections are powerful data structures. Next, let's explore error handling to make your code more robust.