Arrays in JavaScript are high-performacne, list-like objects. They use numeric indices starting from 0. This guide covers core array operations and common Lodash utilities for more advanced tasks.
Basic Array Characteristics and Operations
- Array length:
arr.length - Modifying length:
- If you set a larger length, the extra slots become empty (not actually
null, they are empty slots). - If you set a smaller length, elements at the end are removed.
- If you set a larger length, the extra slots become empty (not actually
let arr1 = [11, 12, 13];
let arr2 = [21, 22, 23];
arr1.length = 1; // [11]
arr2.length = 5; // [21, 22, 23, empty × 2]
-
Check if something is an array:
Array.isArray(arr)arr instanceof Arrayworks too, but is less reliable across different execution contexts.
-
Check if array contains a value:
arr.includes()
[1, 2, 3].includes(2); // true
// The second argument is the starting index (default 0). Negative values count from the end.
[1, 2, 3].includes(3, 3); // false
Creating Arrays
Method 1: Literal
let arr1 = [];
let arr2 = [1, 2, 3];
Method 2: Constructor
let arr1 = new Array(); // []
let arr2 = new Array(4); // [empty × 4]
let arr3 = new Array(15, 16, 17); // [15, 16, 17]
Method 3: Array.of()
Creates an array from its arguments, regardless of their number or type.
let arr = Array.of(1, 'abc', true);
Method 4: Converting Array-like Objects
Use Array.from() to convert array-like objects (like arguments or NodeLists) into true arrays.
Iterating Over Arrays
for...of (Recommended)
Iterates over array elements. Avoids polluting the scope with the index variable.
for (let item of arr) {
console.log(item);
}
// Can use break or return to exit early
for (let item of arr) {
if (item === 'a') {
console.log(item);
break;
}
}
forEach()
Executes a function for each element. Has no return value and cannot be broken with break. It returns undefined by default.
arr.forEach((item, index, arr) => {
// callback logic
});
- To skip the current iteration, use
return. - To exit the loop entirely, use
try...catch(not recommended).
let arr = ['a', 'b', 'c', 'd'];
arr.forEach((item, index) => {
if (item === 'b') {
return; // skip 'b'
}
console.log(item);
});
// Output: a, c, d
Traditional for Loop
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
map()
Creates a new array with the results of calling a function for every element.
let arr = ['a', 'b', 'c', 'd'];
let newArr1 = arr.map((item, index) => item + index);
// ['a0', 'b1', 'c2', 'd3']
let newArr2 = arr.map((item, index) => ({ index, value: item }));
// [{ index: 0, value: 'a' }, ...]
let newArr3 = arr.map((item, index) => {
if (item === 'b') { return item; }
// If no return, the element becomes undefined
});
// [undefined, 'b', undefined, undefined]
reduce()
Reduces the array to a single value by executing a reducer function.
let arr = [1, 2, 3, 4];
let sum = arr.reduce((x, y) => x + y); // 10
let product = arr.reduce((x, y) => x * y); // 24
every()
Tests whether all elements pass the provided function. Returns true only if all tests pass.
let arr = ['a', 'b', 'good', 'd'];
let result = arr.every((item, index, arr) => {
return item.length < 2;
});
// false, because 'good' has length 4
let result2 = arr.every(item => item.length > 0);
// true
some()
Tests whether at least one element passes the provided function. Returns true as soon as one passes.
let arr = ['a', 'b', 'good', 'd'];
let result = arr.some(item => item.length < 2);
// true, because 'a' passes
Accessing Elements
Use bracket notation with the index. Accessing a non-existent index returns undefined.
let arr = [21, 22, 23];
console.log(arr[0]); // 21
console.log(arr[5]); // undefined
Finding Elements arr.find()
Returns the first element that satisfies the testing function.
let arr = [2, 3, 2, 5, 7, 6];
let result = arr.find(item => item > 4); // 5
Adding Elements
- Beginning:
arr.unshift(element1, element2, ...)— returns new length. - End:
arr.push(element1, element2, ...)— returns new length. - Any index:
arr[index] = value- If the index is within bounds, it replaces the value.
- If the index equals the length, it appends.
- If the index is greater than the length, the gap is filled with empty items.
Removing Elements
Removing First / Last Element
let removedFirst = arr.shift(); // returns removed element
let removedLast = arr.pop(); // returns removed element
Clearing an Array
arr = []; // Recommended
arr.length = 0; // Alternative
arr.splice(0); // Alternative
splice() — General Purpose Removal / Insertion
let arr = ['a', 'b', 'c', 'd', 'e', 'f'];
// Start at index 1, delete 3 elements, then insert new elements at that position
let removed = arr.splice(1, 3, 'new1', 'new2');
console.log(arr); // ['a', 'new1', 'new2', 'e', 'f']
console.log(removed); // ['b', 'c', 'd']
Joining Elements
Converts an array to a string.
join()
let arr = ['a', 'b', 'c'];
console.log(arr.join()); // 'a,b,c'
console.log(arr.join('-')); // 'a-b-c'
toString()
console.log(arr.toString()); // 'a,b,c'
Finding Indices
indexOf() and lastIndexOf()
Returns the first (or last) index of a given element, or -1 if not found.
let arr = ['a', 'b', 'c', 'a'];
console.log(arr.indexOf('a')); // 0
console.log(arr.lastIndexOf('a')); // 3
findIndex()
Returns the index of the first element that satisfies the testing function.
let arr = [2, 3, 2, 5, 7, 6];
let result = arr.findIndex(item => item > 4); // 3
Lodash: _.findLastIndex() to search from right to left.
Copying Arrays
Shallow Copy
let arr2 = arr1;
Deep Copy
For deep copying nested arrays/objects, Lodash provides _.cloneDeep().
Getting Max / Min Values
- ES6 Spread Operator:
Math.max(...arr) - ES5
apply:Math.max.apply(null, arr) - Manual Loop: iterate and compare.
sort():arr.sort((a,b) => a - b)[0]for min,arr.sort((a,b) => b - a)[0]for max.reduce():arr.reduce((min, val) => min < val ? min : val)for min.- Lodash:
_.max([4, 2, 8, 6])returns8.
Summing Arrays
Lodash: _.sum([4, 2, 8, 6]) returns 20.
Extracting Sub-arrays arr.slice()
Does not mutate the original array.
let arr = ['a', 'b', 'c', 'd', 'e', 'f'];
let result1 = arr.slice(2); // ['c', 'd', 'e', 'f']
let result2 = arr.slice(-2); // ['e', 'f']
let result3 = arr.slice(2, 4); // ['c', 'd']
let result4 = arr.slice(4, 2); // []
Filtering Arrays arr.filter()
Creates a new array with all elements that pass the test.
const arr1 = [1, 3, 6, 2, 5, 6];
const arr2 = arr1.filter(item => item > 4); // [6, 5, 6]
Lodash: _.compact(array) removes all falsy values (false, null, 0, "", undefined, NaN).
Sorting arr.sort()
Mutates the original array.
let arr = [1, 10, 2, 12];
let sorted = arr.sort((a, b) => b - a); // [12, 10, 2, 1]
Reversing arr.reverse()
Mutates the original array.
let arr = ['a', 'b', 'c'];
let reversed = arr.reverse(); // ['c', 'b', 'a']
Deduplicating Arrays
For Primitive Arrays
Lodash: _.uniq([2, 1, 2]) returns [2, 1].
Manual Approach
Create a new array and only push elements that are not already present.
For Object Arrays (by a specific key)
function uniqByKey(arr, key) {
let seen = {};
return arr.reduce((unique, item) => {
if (!seen[item[key]]) {
seen[item[key]] = true;
unique.push(item);
}
return unique;
}, []);
}
let arr = [
{ key: '01', value: '乐乐' },
{ key: '01', value: '乐乐' },
{ key: '02', value: '博博' }
];
console.log(uniqByKey(arr, 'key'));
// [ { key: '01', value: '乐乐' }, { key: '02', value: '博博' } ]
Concatenating Arrays arr.concat()
let arr1 = [1, 2, 3];
let arr2 = ['a', 'b', 'c'];
let merged = arr1.concat(arr2); // [1, 2, 3, 'a', 'b', 'c']
Set Operations (Intersection, Difference, etc.)
Using Set for primitive arrays:
let a = [1, 2, 3, 4, 5];
let b = [2, 4, 6, 8, 10];
let setB = new Set(b);
// Intersection: elements in both
let intersection = a.filter(x => setB.has(x)); // [2, 4]
// Difference: elements in a but not in b
let difference = a.filter(x => !setB.has(x)); // [1, 3, 5]
// Symmetric difference: elements not in both
let symmetricDiff = [
...a.filter(x => !setB.has(x)),
...b.filter(x => !new Set(a).has(x))
]; // [1, 3, 5, 6, 8, 10]
// Union: all unique elements from both
let union = [...new Set([...a, ...b])]; // [1, 2, 3, 4, 5, 6, 8, 10]
Chunking Arrays (Lodash)
Splits an array into groups of a specified size.
_.chunk(['a', 'b', 'c', 'd'], 3);
// [['a', 'b', 'c'], ['d']]
Filling Arrays (Lodash)
let arr = [1, 2, 3];
_.fill(arr, 'a');
// arr is now ['a', 'a', 'a']
_.fill([4, 6, 8, 10], '*', 1, 3);
// [4, '*', '*', 10]
Reorganizing Arrays (Lodash)
Zip / Unzip
let zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
// [['fred', 30, true], ['barney', 40, false]]
_.unzip(zipped);
// [['fred', 'barney'], [30, 40], [true, false]]
Zip Object
_.zipObject(['a', 'b'], [1, 2]);
// { a: 1, b: 2 }
Group By
_.groupBy([6.1, 4.2, 6.3], Math.floor);
// { '4': [4.2], '6': [6.1, 6.3] }
Counting Elements (Lodash)
_.countBy([6.1, 4.2, 6.3], Math.floor);
// { '4': 1, '6': 2 }
Flattening Arrays (Lodash)
_.flatMap([1, 2], n => [n, n]);
// [1, 1, 2, 2]
Random Sampling (Lodash)
Single Sample
_.sample([1, 2, 3, 4]); // e.g., 2
Multiple Samples
_.sampleSize([1, 2, 3], 2); // e.g., [3, 1]
Shuffling (Lodash)
_.shuffle([1, 2, 3, 4]); // e.g., [4, 1, 3, 2]
Partitioning Arrays (Lodash)
Splits an array into two groups based on a predicate.
let users = [
{ 'user': 'barney', 'age': 36, 'active': false },
{ 'user': 'fred', 'age': 40, 'active': true },
{ 'user': 'pebbles', 'age': 1, 'active': false }
];
_.partition(users, 'active');
// [[fred], [barney, pebbles]]