JavaScript Array Methods
An Array on its own is just a container. To make it useful, we need to add items, remove them, find them, or reorganize them. JavaScript provides built-in functions called Methods to handle these tasks.
A key concept in this lesson is Mutability:
- Mutating Methods: Change the original array directly.
- Non-Mutating Methods: Leave the original array alone and return a new copy or value.
When working with mutating methods, you can prevent unintended side effects by first creating a shallow copy of the original array using the spread operator ([...]), Array.from(), or .slice(). However, keep in mind that shallow copies only duplicate the top-level structure; if your array contains nested objects or arrays, those internal references still point to the original data. To fully decouple nested structures, you must perform a deep copy using structuredClone() or the older JSON.parse(JSON.stringify()) method, though the latter should be used with caution as it cannot clone special data types like functions or undefined.
1. Adding & Removing Items (Mutating)
These methods directly change the array’s contents and length.
The Stack (End)
.push(item): Adds one or more items to the end. Returns the new length..pop(): Removes the last item. Returns the removed item.
const stack = [1, 2];
stack.push(3); // Add "3" to end of array.
console.log(stack); // Output: [1, 2, 3]
const removed = stack.pop(); // Remove "3" from end of array.
console.log(stack); // Output: [1, 2]
console.log(removed); // Output: 3
// Copy array with ...spread to keep original array intact:
const originalArray = [1, 2, 3];
const copiedArray = [...originalArray];
const pushThis = "four";
copiedArray.push(pushThis);
console.log(originalArray); // Output: [1, 2, 3]
console.log(copiedArray); // Output: [1, 2, 3, "four"]
// Push returns array length without argument in param:
console.log(copiedArray.push());
// Output: 4 (length of array)
/* Note: see "shallow copy" vs. "deep copy" reference above
to know what to use when making copies of your array. */JavaScriptThe Queue (Start)
.unshift(item): Adds one or more items to the start. Returns the new length..shift(): Removes the first item. Returns the removed item.
const queue = ["B", "C"];
queue.unshift("A");
console.log(queue); // Output: ["A", "B", "C"]
const firstItem = queue.shift();
console.log(queue); // Output: ["B", "C"]
console.log(firstItem); // Output: A
console.log(queue.shift()); // Output: B
console.log(queue); // Output: ['C']
console.log(queue.unshift("one", "two"));
// Output: 3 (length of top-level array elements)
console.log(queue); // Output: ['one', 'two', 'C']JavaScriptThe Swiss Army Knife
.splice(start, deleteCount, itemsToAdd): Adds, removes, or replaces items anywhere.
const months = ["Jan", "April", "June", "July"];
// .splice(Start Index, Delete Count, Items to Add...)
// Start at index 1 ("April"), delete 0 items, then insert "Feb" and "March"
months.splice(1, 0, "Feb", "March");
console.log(months);
// Output: ['Jan', 'Feb', 'March', 'April', 'June', 'July']
// When you omit the second parameter, it deletes EVERYTHING from the Start Index to the end
months.splice(4);
console.log(months);
// Output: ['Jan', 'Feb', 'March', 'April'] (June & July deleted)
// Start at index 2 ("March"), delete 1 item (which is "March"), then insert "Holiday"
months.splice(2, 1, "Holiday");
console.log(months);
// Output: ['Jan', 'Feb', 'Holiday', 'April']
// Count from the end with a negative splice() start value:
let nums = [1, 2, 3, 4, 5];
nums.splice(-2, 1); // Remove the "4"
console.log(nums); // Output: [1, 2, 3, 5]
nums.splice(-1, 0, 4); // Add "4" back
console.log(nums); // Output: [1, 2, 3, 4, 5]JavaScript2. Reordering (Mutating)
These methods rearrange the items inside the original array.
.reverse(): Reverses the order of the elements in place..sort(): Sorts the elements in place.- Warning: By default, it sorts by string value, meaning
10comes before2because.sort()converts array items to strings by default. You need a “compare function” aka “comparator” callback function for numbers.
- Warning: By default, it sorts by string value, meaning
// Reverse Array Order
const letters = ["a", "b", "c"];
letters.reverse();
console.log(letters);
// Output: ["c", "b", "a"]
// Sort Words - Alphabetical (lexicographically)
console.log(letters.sort());
// Output: ["a", "b", "c"]
// Sort Numbers - Alphabetical (lexicographically) - 10 before 2.
const nums = [5, 1, 10, 2];
nums.sort();
console.log(nums); // [1, 10, 2, 5]JavaScriptTo correct number sorting, the .sort() method takes a compare function (callback) which makes .sort() a higher-order function. This can be written as an arrow function (using an implicit return) or a standard function (requiring an explicit return keyword).
The JavaScript engine doesn’t just sort randomly; it passes two items into the callback function parameters ($a, b$) to determine their relationship based on the result: negative (keep $a$ before $b$), positive (move $a$ after $b$), or zero (no change). While this ‘compare-and-swap’ logic is similar to a Bubble Sort, modern engines use Timsort, a more efficient hybrid algorithm that scans for pre-existing patterns (‘runs’) in the data.
Note: Even though the engine’s rules are fixed, you control the outcome with your math. Using a - b creates a negative result when a is smaller (Ascending), while using b - a creates a negative result when a is larger (Descending).
const nums = [5, 1, 10, 2];
nums.sort((a, b) => a - b); // Implicit/Automatic Return
// Ascending (a - b)
console.log(nums); // [1, 2, 5, 10]
nums.sort(function(first, second){
return second - first // Explicit requires Return
}); // Descending (b - a)
console.log(nums); // Output: [10, 5, 2, 1]
const nameList = ["Bob", "Harry", "Mary", "Ricky Bobby", "Leeroy"]
nameList.sort((short, long) => short.length - long.length)
console.log(nameList);
// Output: ['Bob', 'Mary', 'Harry', 'Leeroy', 'Ricky Bobby']JavaScriptInstead of using “a – b” for Ascending or “b – a” for Descending with .sort(), we can provide a 1, -1, or 0 value in our callback function to be sorted directly and demystify how the JavaScript Engine interprets the callback. Note: the order in which the engine picks pairs depends on the algorithm’s strategy, but ‘a’ always represents the first item in the comparison pair.
// Ascending Order:
const nums = [5, 1, 10, 2, 10];
const sorting = nums.sort((a, b) => {
if (a < b) {
console.log(`Less than: Move ${a} before ${b} = -1`);
return -1
} else if (a > b) {
console.log(`Greater than: Keep ${a} after ${b} = 1`);
return 1
} else {
console.log(`Equal: Keep ${a} after ${b} = 0`);
return 0
}
});
console.log(nums); // Output: [1, 2, 5, 10]
// Descending Order:
const nums2 = [5, 1, 10, 2, 10];
const sorting2 = nums2.sort((a, b) => {
if (a > b) {
console.log(`Greater than: Move ${a} before ${b} = -1`);
return -1
} else if (a < b) {
console.log(`Less than: Keep ${a} after ${b} = 1`);
return 1
} else {
console.log(`Equal: Keep ${a} after ${b} = 0`);
return 0
}
});
console.log(nums2); // Output: [10, 10, 5, 2, 1]JavaScriptHere’s another example of decoding comparison sorting by console logging the a, b compare sorting. This time we’ll see the value from the comparison instead of 1, -1, or 0.
// Ascending Order
const nums = [5, 2, 8, 1];
console.log(nums);
nums.sort((a, b) => {
const result = a - b;
// If result is negative, 'a' (the new item) belongs to the left of 'b'
const action = result < 0 ? `Move ${a} before ${b}` : `Keep ${a} after ${b}`;
console.log(`New Item: ${a} | Comparing vs: ${b} | Result: ${result} | Action: ${action}`);
return result;
}); /*
New Item: 2 | Comparing vs: 5 | Result: -3 | Action: Move 2 before 5
New Item: 8 | Comparing vs: 5 | Result: 3 | Action: Keep 8 after 5
New Item: 1 | Comparing vs: 5 | Result: -4 | Action: Move 1 before 5
New Item: 1 | Comparing vs: 2 | Result: -1 | Action: Move 1 before 2
*/console.log(nums); // Output: [1, 2, 5, 8]
// Descending Order
const nums2 = [5, 2, 8, 1];
nums2.sort((a, b) => {
const result = b - a;
// For Descending: Positive means 'b' is bigger, so move 'a' to the right.
const action = result > 0 ? `Move ${a} (smaller) Right` : `Keep ${a} (larger) Left`;
console.log(`New: ${a} | Vs: ${b} | Result: ${result} | ${action}`);
return result;
}); /*
New: 2 | Vs: 5 | Result: 3 | Move 2 (smaller) Right
New: 8 | Vs: 2 | Result: -6 | Keep 8 (larger) Left
New: 8 | Vs: 5 | Result: -3 | Keep 8 (larger) Left
New: 1 | Vs: 5 | Result: 4 | Move 1 (smaller) Right
New: 1 | Vs: 2 | Result: 1 | Move 1 (smaller) Right
*/ console.log(nums2); // Output: [8, 5, 2, 1]JavaScriptUsing .localeCompare() instead of .sort() for Strings (Preferred)
By default, .sort() uses Unicode values. This creates two major issues in professional apps:
- Case Sensitivity: Uppercase “Z” comes before lowercase “a” (because “Z” has a lower character code).
- Accents/Special Characters: It doesn’t know that “é” should be treated similarly to “e”.
The localeCompare() method returns the exact numbers that .sort() needs: -1, 1, or 0.
const names = ["Zebra", "apple", "Ángel"];
names.sort();
console.log(names);
// Output: ["Zebra", "apple", "Ángel"] (Unicode order)
names.sort((a, b) => a.localeCompare(b));
console.log(names);
// Output: ["apple", "Ángel", "Zebra"] (Dictionary order)
// Basic localeCompare() comparison without .sort():
const string1 = "apple";
const string2 = "banana";
// 'apple' comes before 'banana' alphabetically.
// The result is a negative number (e.g., -1).
let result1 = string1.localeCompare(string2);
console.log(`"${string1}" compared with "${string2}": ${result1}`);
// Output: "apple" compared with "banana": -1JavaScriptlocaleCompare() accepts two optional arguments: locales and options.
- The
localesargument specifies the language whose sort order should be used (i.eenfor English,esfor Spanish,defor German, orundefinedfor default). If omitted, the browser’s default locale is used. - The
optionsargument is an object that customizes the comparison behavior.- Key options (which each have different values of their own) include:
usage,sensitivity,ignorePunctuation,numeric,caseFirstandcollation.
- Key options (which each have different values of their own) include:
const items = ["banana", "Apple", "apple"];
items.sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));
console.log(items);
// Output: ["Apple", "apple", "banana"]
// (Treated A and a as the same "base" letter)
const files = ["file10.txt", "file2.txt", "file1.txt"];
files.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
console.log(files);
// Output: ["file1.txt", "file2.txt", "file10.txt"]JavaScriptReal-world example sorting two different values using both .sort() and localeCompare() with a JavaScript Object (covered in next lesson).
const products = [
{ name: "Laptop", category: "Electronics", price: 1200 },
{ name: "Toaster", category: "Appliances", price: 50 },
{ name: "Phone", category: "Electronics", price: 800 },
{ name: "Blender", category: "Appliances", price: 100 }
];
products.sort((a, b) => {
// 1. First, compare the categories (Alphabetical)
// localeCompare returns -1, 1, or 0
const categorySort = a.category.localeCompare(b.category);
// 2. If categories are NOT the same, use the category order
if (categorySort !== 0) {
return categorySort; // Exit function with sorted categories
}
// 3. If categories ARE the same (0), use the price to break the tie (Ascending)
return a.price - b.price; // Exit function w/ sorted categories then price
});
console.log(products);
/* Output:
[
{ name: "Toaster", category: "Appliances", price: 50 }, <- Appliances first
{ name: "Blender", category: "Appliances", price: 100 }, <- Then by price
{ name: "Phone", category: "Electronics", price: 800 }, <- Electronics second
{ name: "Laptop", category: "Electronics", price: 1200 } <- Then by price
]
*/JavaScriptComparing .sort() and localeCompare() Summary:
| Feature | Default .sort() | localeCompare() |
| Logic | Unicode Character Codes | Language-specific dictionary rules |
| Cases | Uppercase before lowercase | Case-aware (user-friendly) |
| Accents | Puts “á” at the very end | Sorts “á” near “a” |
| Best For | Simple IDs or Symbols | Names, Titles, and User-facing text |
3. Creating New Arrays (Non-Mutating)
These methods allow you to manipulate data without destroying the original list. They return a brand new array. These methods also work on the string data type.
Slicing & Concatenating
.slice(start, end): Returns a copy of a section of an array..concat(array2): Merges two or more arrays.
const animals = ["Rabbit", "Deer", "Fox", "Bear"];
// Slice (index start, index end):
const wholeArray = animals.slice(0, 4);
console.log(wholeArray); // Output: ["Rabbit", "Deer", "Fox", "Bear"]
// Parameter #2 is a stop-index (doesn't include index #3):
const middleTwo = animals.slice(1, 3);
console.log(middleTwo); // Output: ['Deer', 'Fox']
// Negatives slice from the end of the array:
const negSlice = animals.slice(0, -1);
console.log(negSlice); // Output: ['Rabbit', 'Deer', 'Fox']
const nestedAnimals = [["Rabbit", "Deer",], ["Fox", "Bear"]];
console.log(nestedAnimals[1].slice(1, 2)); // Output: ["Bear"]JavaScript// Concat Method
const birds1 = ["Owl", "Eagle"];
const birds2 = ["Chicken", "Turkey"];
const allBirds = birds1.concat(birds2);
console.log(allBirds); // Output: ['Owl', 'Eagle', 'Chicken', 'Turkey']
const newBird = "Hawk";
const objBird = {Bird: "Falcon"};
console.log(birds1.concat(birds2, newBird, objBird));
// Output: ['Owl', 'Eagle', 'Chicken', 'Turkey', 'Hawk', {Bird: 'Falcon'}]JavaScriptTransforming (Functional Methods)
These are powerful methods used in modern frameworks like React.
.map(fn): transform every item and return a new array of the same length..filter(fn): Returns a new array containing only items that pass a true/false boolean test..join(separator): Joins all elements into a single String.
// Map new array with array index plus 10:
console.log([1,2,3].map(x => x + 10));
// Output: [11, 12, 13]
// Map new array with original #s divided by 2:
const numbers = [10, 20, 30];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // Output: [20, 40, 60]
// Map new array rounded with 2 decimals and $ sign:
const prices = [10.5, 20, 35.99];
const formattedPrices = prices.map(price => {
return `$${price.toFixed(2)}`;
});
console.log(formattedPrices); // Output: ["$10.50", "$20.00", "$35.99"]
// Map new array with uppercase strings:
const names = ["toronto", "london", "new york"];
const upperCaseNames = names.map(name => name.toUpperCase());
console.log(upperCaseNames); // Output: ["TORONTO", "LONDON", "NEW YORK"]
// Map new array with square root of index:
const numbers2 = [4, 9, 16, 25];
const roots = numbers2.map(Math.sqrt);
console.log(roots); // Output: [2, 3, 4, 5]
// Map/extract Object Properties in array to new array:
const gameResults = [
{id: 1, userName: "Rodney", console: "PC"},
{id: 2, userName: "Dersha", console: "PS5"},
{id: 3, userName: "Beck", console: "Nintendo"}
];
const userInfo = gameResults.map(user => user.console);
console.log(userInfo); // Output: ['Rodney', 'Dersha', 'Beck']
// Map/add a New Object Property to a new array:
const products = [
{name: "iPhone", price: "1,200"},
{name: "Android", price: "800"},
{name: "Laptop", price: "2,200"}
];
const productsWithTax = products.map(product => {
return {
...product,
productsWithTax: product.price.replace(',','') * 1.2
// Type Coercion converts string to number without comma
};
});
console.log(productsWithTax)
/* Output: [
{name: 'iPhone', price: '1,200', productsWithTax: 1440}
{name: 'Android', price: '800', productsWithTax: 960}
{name: 'Laptop', price: '2,200', productsWithTax: 2640}
] */
// Map with additional parameter/argument:
const items = ['apple', 'banana', 'cherry'];
// "index","item","array" are built-in parameters with map()
// They must be in this order (item, index, array)
// (item, index) can be used without the "array" param
const indexedItems = items.map((item, index, array) => {
return `Item at index ${index}: ${item} | Array: ${array}`;
});
console.log(indexedItems);
/* Output: [
'Item at index 0: apple | Array: apple,banana,cherry',
'Item at index 1: banana | Array: apple,banana,cherry',
'Item at index 2: cherry | Array: apple,banana,cherry'
] */JavaScript// Filter new array with numbers >= 10
const numbers = [13, 5, 10, 6, 18];
const greaterThanTen = numbers.filter(num => num >= 10);
console.log(greaterThanTen); // Output: [13, 10, 18]
// Filter new array with even numbers
//const numbers = [13, 5, 10, 6, 18];
const myCallback = (pass2callback) => {
return pass2callback % 2 === 0;
};
const evenNumbers = numbers.filter(myCallback);
console.log(evenNumbers); // Output: [10, 6, 18]
// Filter an array of unique numbers by checking for the first index of a number.
const numArray = [13, 5, 10, 13, 6, 18, 5];
// "item" (or currentValue): The current element being processed in the array. This is the first argument provided to the callback function.
// "index" (or currentIndex): The index of the current element being processed. This is the second argument.
// "array" (or arrayRef): A reference to the original array that filter was called upon. This is the third argument.
const uniqueNumbers = numArray.filter((item, index, array) => {
// .indexOf(item) always returns the VERY FIRST index where it finds the item
const firstPosition = array.indexOf(item);
// LOGIC: If the current index is the same as the first position, it's the original.
// If they are different, it means we've seen this item before (it's a duplicate).
const isOriginal = index === firstPosition;
console.log(`Item: ${item} | Index: ${index} | First Seen At: ${firstPosition} | Keep? ${isOriginal}`);
return isOriginal;
});
/* Item: 13 | Index: 0 | First Seen At: 0 | Keep? true
Item: 5 | Index: 1 | First Seen At: 1 | Keep? true
Item: 10 | Index: 2 | First Seen At: 2 | Keep? true
Item: 13 | Index: 3 | First Seen At: 0 | Keep? false
Item: 6 | Index: 4 | First Seen At: 4 | Keep? true
Item: 18 | Index: 5 | First Seen At: 5 | Keep? true
Item: 5 | Index: 6 | First Seen At: 1 | Keep? false */
console.log(uniqueNumbers); // Output [13, 5, 10, 6, 18]JavaScript// Joining arrays keeps the comma by default:
const colors = ["red", "blue", "green"];
console.log(colors.join());
// Output: red,blue,green
// Join an array and replace the comma with a dash:
const myNums = [2, 3, 4,];
const csv = myNums.join("-");
console.log(csv); // Output: 2-3-4
// Join array items without the comma:
const letters = ["H", "e", "l", "l", "o"];
console.log(letters.join(""));
// Output: Hello
// Joining null or undefined items are treated as empty strings:
const data = [1, undefined, "String", null, 3];
console.log(data.join());
// Output: 1,,Hello,,3JavaScript4. Searching & Finding (Non-Mutating)
Methods to locate specific items or their positions.
.includes(item): Returnstrueif the item exists..indexOf(item): Returns the index of the first match (or-1)..find(fn): Returns the first item that satisfies a testing function..findIndex(fn): Returns the index of the first item that satisfies a testing function.
// includes() String Method Reminder:
const colors = "red, blue, green";
console.log(colors.includes(", blue")); // Output: true
console.log(colors.includes("Red")); // Output: false
// includes() is case sensitive.
// includes() Array Method:
const numbers = [10, 20, 30, 40, 50];
console.log(numbers.includes(30)); // Output: true
console.log(numbers.includes(31)); // Output: false
// Search for 30 starting from index 3
console.log(numbers.includes(30, 3));
// Output: false (because 30 appears before index 3)
console.log(numbers[3]); // Output: 40
// Search for 40 starting from index 3
console.log(numbers.includes(40, 3));
// Output: trueJavaScript// indexOf() String Method Reminder:
const newColors = "black, purple, brown";
console.log(newColors.indexOf("B"));
// Output: -1 (case sensitive)
console.log(newColors.indexOf("b"));
// Output: 0 (returns the first index of the character)
// indexOf() Array Method:
const fruits = ["orAnge", "apple", "banana"];
console.log(fruits.indexOf("apple")); // Output: 1
// Mapping a new array toLowerCase to address case sensitivity:
console.log(fruits.map(fruit => fruit.toLowerCase()).indexOf("orange"));
// Output: 0 (now that the array is all lowercase)
// indexOf() from a specific index:
const numberInd = [10, 20, 30, 40, 20, 50];
console.log(numberInd.indexOf(20, 2));
// Output: 4 (starts search at index 2 (30), finds "20" at index 4)
// Check user permissions with indexOf():
const userDetails = [
{ profile: "public" },
{ permissions: ["read", "write", "delete"] },
{ darkMode: true },
];
if (userDetails[1].permissions.indexOf("write") !== -1) {
// Execute "write" permissions code.
console.log("User has write permissions.");
}
if (userDetails[1].permissions.indexOf("delete") !== -1) {
// Execute "delete" permissions code.
console.log("User has delete permissions.");
}JavaScript/* .find() Array Method:
(element, index, array)
element (or currentValue): The current element being processed in the array.
index (optional): The index of the current element being processed.
array (optional): The original array that find() was called upon. */
// Finding the first number > 10:
const numbers = [5, 12, 8, 130, 44];
const found = numbers.find(element => element > 10);
console.log(found); // Output: 12
// Find the first string with .toLowerCase() for case sensitivity:
const sports = ["Football", "Baseball", "Hockey", "Baseketball"];
const findSport1 = sports.find(sport => sport.includes("base"));
console.log(findSport1); // Output: undefined
const findSport2 = sports.find(sport => sport.toLowerCase().includes("base"));
console.log(findSport2); // Output: Baseball
// Find the first string that starts with "m"
const trees = ["birch", "maple", "oak", "poplar"];
const result = trees.find(tree => tree.startsWith("m"));
console.log(result); // Output: "maple"
// .startsWith() Example (case sensitive):
console.log("Hello".startsWith("We")); // Output: false
console.log("Hello".startsWith("He")); // Output: true
// Finding complex data (like objects)
const people = [
{id: 1, name: "Jen"},
{id: 2, name: "Bob"}
];
// Find the actual object
const findBob = people.find(person => person.id === 2);
console.log(findBob); // {id: 2, name: "Bob"}
// Finding items with a price less than 600:
const items = [
{ name: "Laptop", price: 1000 },
{ name: "Tablet", price: 500 },
{ name: "Phone", price: 300 }
];
const affordableItem = items.find(item => item.price < 600);
console.log(affordableItem); // Output: { name: "Tablet", price: 500 }
// Reminder: to return all matches, use .filter() instead of .find():
const affordableItem2 = items.filter(item => item.price < 600);
console.log(affordableItem2);
// Output: { name: "Tablet", price: 500 } { name: "Phone", price: 300 }
// Finding number with element and index:
const numbersTwo = [5, 12, 8, 130, 44];
const foundNum = numbersTwo.find((element, index) => {
// If there is a number with a remainder of 0
// AND the array index is greater than 1 (1 index is 12)
const isTrue = element % 2 === 0 && index > 1;
return isTrue;
});
console.log(foundNum); // Output: 8
// Using all three (element, index, array) parameters:
// Find the first temperature that is higher than the one BEFORE it
const temps = [77, 72, 68, 85, 90];
const spike = temps.find((element, index, array) => {
// Skip the first index because there's no previous array to compare.
if (index === 0) return false;
// Get the previous array to compare to current element
const previous = array[index - 1];
return element > previous;
});
console.log(spike); // Output: 85 (Because 85 > 68)JavaScript/* .findIndex() Array Method:
(element, index, array)
element (or currentValue): The current element being processed in the array.
index (optional): The index of the current element being processed.
array (optional): The original array that find() was called upon. */
// Find the index of the first occurrence of the number 7
const numbers = [3, 1, 4, 5, 7, 8, 10, 7];
const index = numbers.findIndex(element => element === 7);
console.log(index);
// Output: 4
// (The first 7 is at index 4)
const index2 = numbers.findIndex(element => {
const findIt = element < 7 && element % 2 === 0;
return findIt;
});
console.log(index2);
// Output: 2 (index 2)
// Find the object property index in an array:
const people = [
{id: 11, name: "Bob"},
{id: 22, name: "Beck"},
{id: 33, name: "Barry"}
];
const barryIndex = people.findIndex(person => person.id === 33);
console.log(barryIndex); // Output: 2 (index 2)
// .findIndex() with all three parameters (element, index, array):
const languages = ["HTML", "CSS", "JavaScript", "React"];
let targetIndex = languages.findIndex((element, index, array) => {
// Logging will show how many iterations to get to the desired index:
console.log(`Element: ${element} | Index: ${index} | Array: ${array.join(" ")}`);
// The condition accesses the array via the 'array' parameter:
return array[index] === "CSS";
});
console.log(`The index of JavaScript is: ${targetIndex}`);
/* Output:
Element: HTML | Index: 0 | Array: HTML CSS JavaScript React
Element: CSS | Index: 1 | Array: HTML CSS JavaScript React
The index of CSS is: 1 */
// Find Index of an element < leftElement && element < rightElement:
const data = [10, 20, 5, 50, 40];
const localMinimumIndex = data.findIndex((element, index, array) => {
const leftNeighbor = array[index - 1];
const rightNeighbor = array[index + 1];
// Check if it has both left and right neighbors and is smaller than both
if (index > 0 && index < array.length - 1) {
return element < leftNeighbor && element < rightNeighbor;
}
return false;
});
console.log(localMinimumIndex);
// Output: 2 (The element 5 at index 2 is smaller than 20 and 50)JavaScript5. Logical Checks & Aggregation
.some(fn): Returnstrueif at least one item passes the test..every(fn): Returnstrueonly if ALL items pass the test..reduce(fn, initialValue): Reduces the array to a single value (like a total sum).
/* .some() Array Method:
(element, index, array)
element (or currentValue): The current element being processed in the array.
index (optional): The index of the current element being processed.
array (optional): The original array that find() was called upon. */
// .some() - is there an element equal to 3:
const numbers = [1, 2, 4, 5];
const index = numbers.some(element => element === 3);
console.log(index);
// Output: false (there is no "3")
// .some() - is there an element with index > 2 and even:
const index2 = numbers.some((element, index) => {
const findIt = index > 1 && element % 2 === 0;
return findIt;
});
console.log(index2);
// Output: true
// .some() with all three parameters (element, index, array):
const languages = ["HTML", "CSS", "JavaScript", "React"];
let targetIndex = languages.some((element, index, array) => {
// Logging will show how many iterations to get to find true condition:
console.log(`Element: ${element} | Index: ${index} | Array: ${array.join(" ")}`);
// The condition accesses the array via the 'array' parameter:
return array[index] === "CSS";
});
console.log(targetIndex);
/* Output:
Element: HTML | Index: 0 | Array: HTML CSS JavaScript React
Element: CSS | Index: 1 | Array: HTML CSS JavaScript React
true */JavaScript/* .every() Array Method:
(element, index, array)
element (or currentValue): The current element being processed in the array.
index (optional): The index of the current element being processed.
array (optional): The original array that find() was called upon. */
// .every() Check if every element meet the condition:
const scores = [80, 90, 100];
// Is every() number greater than 60?
const allGreater = scores.every(element => element > 60);
console.log(allGreater); // true
// Is every() number even (remainder of 0 when divided by 2)?
const allEven = scores.every(element => element % 2 === 0);
console.log(allEven); // true
const names = ["Bobby", "Sandy", "Willy"];
// Does every() name include the letter "a"?
const allAChar = names.every(element => element.includes("a"));
console.log(allAChar); // false
// Does every() name include the letter "y"?
const allYChar = names.every(element => element.includes("y"));
console.log(allYChar); // trueJavaScript/* .reduce() has 4 total parameters:
(accumulator, currentValue, index, array)
with index & array being optional.
*/
// Calculate Total (Accumulator starts at 90)
const scores = [80, 90, 100];
const total = scores.reduce((total, score) => total + score, 90);
console.log(total); // 360 (270, 90 = 360)
// Reduce's 4 parameters in use while logging the process:
const initialValue = 90;
const newTotal = scores.reduce((accumulator, currentValue, index, array) => {
// Create a visual folder for each step
console.group(`Iteration ${index + 1}`);
console.log(`Accumulator: ${accumulator}`);
console.log(`Current Value: ${currentValue}`);
const sum = accumulator + currentValue;
console.log(`Iteration end: ${sum}`);
//console.log(`(Same Array: ${array})`);
console.groupEnd(); // Close the folder
return sum;
}, initialValue);
console.log(`Final Result: ${newTotal}`);
const newScores = [2, 1, 5, 10, 8];
// Skip current values less than or equal to 5:
const newTotal2 = newScores.reduce((accumulator, currentValue) => {
if (currentValue <= 5) {
currentValue = 0;}
return accumulator + currentValue
}, 0);
console.log(newTotal2); // Output 18
// Better Way to skip currentValue's with a condition:
const newTotal3 = newScores
.filter(score => score > 5) // [10, 8]
.reduce((accumulator, currentValue) => accumulator + currentValue, 0); // 18
console.log(newTotal3); // Output: 18
// Ternary Way to skip currentValue's with a condition:
const newTotal4 = newScores.reduce((accumulator, currentValue) => {
return currentValue > 5 ? accumulator + currentValue : accumulator;
}, 0);
console.log(newTotal4); // Output: 18
// Using .reduce() to sum values in an Array of Objects:
const startingValue = 0;
const myObjects = [{ num: 1 }, { num: 2 }, { num: 3 }];
const numSum = myObjects.reduce(
(accumulator, currentValue) => accumulator + currentValue.num,
startingValue
);
console.log(numSum); // Output: 6
// Flattening A Multidimensional Array with .reduce() loop:
const multiArray = [
['Bob', 'Bill'],
['Beck', 'Barry'],
['Ben', 'Brad'] ];
const flattenNames = multiArray.reduce((accumulator, currentArray) =>
accumulator.concat(currentArray));
console.log(flattenNames);
// ['Bob', 'Bill', 'Beck', 'Barry', 'Ben', 'Brad']
// Manually flattening instead of looping and adding indexes 1 by 1:
const conc = [];
console.log(conc.concat(multiArray[0],multiArray[1],multiArray[2]));
// Counting Occurrences of Items in an Array:
const arrayItems = ["car", "house", "boat", "house", "car"];
const checkOccurrences = arrayItems.reduce((accumulator, currentValue) => {
// Loop 1: currentValue is "car" using initial empty object as lookup table.
// The code becomes: accumulator["car"] = (undefined || 0) + 1;
// The object now looks like: { car: 1 }
// "0" is used so the value is never undefined which would stop the loop.
accumulator[currentValue] = (accumulator[currentValue] || 0) + 1;
// ^^^^^ OBJECT KEY ^^^^^ ^^^^^^^^^ OBJECT VALUE ^^^^^^^^^^^^^
return accumulator;
}, {}); // Empty object as the initial value.
console.log(checkOccurrences);
// Final Output: {car: 2, house: 2, boat: 1}
// Simple way with one line:
const oneLineOccurrences = arrayItems.reduce((acc, curr) => (acc[curr] = (acc[curr] || 0) + 1, acc), {});
console.log(oneLineOccurrences); // Output: {car: 2, house: 2, boat: 1}
// Grouping Objects by a Property
const foodItems = [
{ name: 'Apple', category: 'Fruit' },
{ name: 'Onion', category: 'Vegetable' },
{ name: 'Orange', category: 'Fruit' },
{ name: 'Lettuce', category: 'Vegetable' }
];
const groupedItems = foodItems.reduce((accumulator, currentItem) => {
const category = currentItem.category;
// Check to see if the accumulator already has an
// object key named after the current category.
// Skip if object.category has been seen by accumulator before:
if (!accumulator[category]) {
// If missing, initialize an empty array for each
// unique Object category value (Fruit, Vegetable)
// inside of the initialized empty accumulator object {}:
accumulator[category] = [];
// { Fruit: [], Vegetable: [] }
}
// Push the currentItem { name: 'Apple', category: 'Fruit' } to the
// new empty arrays by category:
accumulator[category].push(currentItem);
// Alternatively you could just add the name property value:
//accumulator[category].push(currentItem.name);
return accumulator;
}, {});
console.log(groupedItems);
/* Output:
{
Fruit: [ { name: 'Apple', category: 'Fruit' }, { name: 'Orange', category: 'Fruit' } ],
Vegetable: [ { name: 'Onion', category: 'Vegetable' }, { name: 'Lettuce', category: 'Vegetable' } ]
}
*/JavaScript6. Iteration & Properties
.forEach(fn): Executes a function for every item. It does not return a new array (unlike.map)..length: A property (not a method) returning the count of items.
// .forEach() takes up to three parameters (element, index, array):
const cities = ["Paris", "Tokyo"];
cities.forEach(city => console.log(`Traveling to ${city}`));
// Output: Traveling to Paris... Traveling to Tokyo...
const colors = ['red', 'green', 'blue'];
colors.forEach((color, index) => {
console.log(`Color at index ${index} is ${color}`);
});
// Output:
// Color at index 0 is red
// Color at index 1 is green
// Color at index 2 is blue
// Using all three parameters:
const numbers = [10, 20, 30];
let sum = 0;
numbers.forEach(function(number, index, originalArray) {
sum += number;
console.log(`Element ${number} | Index: ${index} | Array [${originalArray}]`);
});
console.log(`Total sum: ${sum}`);
/* Output:
Element 10 | Index: 0 | Array [10,20,30]
Element 20 | Index: 1 | Array [10,20,30]
Element 30 | Index: 2 | Array [10,20,30]
Total sum: 60
*/
let arrayOfObjects = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
];
arrayOfObjects.forEach(obj => {
// Add a new property to each object
obj.newProperty = 'some value';
});
console.log(arrayOfObjects);
/* Output:
[
{ name: 'Alice', age: 25, newProperty: 'some value' },
{ name: 'Bob', age: 30, newProperty: 'some value' }
] */JavaScript// .length can be used for string and arrays:
// String Example:
console.log("String".length);
// Output: 6
// Array Example:
console.log([1,2,3].length);
// Output: 3
// Using logic based on an arrays length:
const numbers = [1, 2, 3, 4, 5];
if (numbers.length > 3) {
numbers.length = 3;
}
console.log(numbers); // Output: [1, 2, 3]
// Filtering and checking array length:
const users = ['Bob', 'Bill', 'Charlie', 'David'];
const filteredUsers = users.filter(user => user.startsWith('B'));
if (filteredUsers.length > 0) {
console.log('Found users starting with B:', filteredUsers);
} else {
console.log('No users found.');
}
// Output: Found users starting with B: ['Bob', 'Bill']JavaScriptSummary Reference
| Method | Basic / Advanced | Description | Mutates? | Returns |
.push() | Basic | Add to end | ✅ Yes | New Length |
.pop() | Basic | Remove from end | ✅ Yes | Removed Item |
.unshift() | Basic | Add to start | ✅ Yes | New Length |
.shift() | Basic | Remove from start | ✅ Yes | Removed Item |
.splice() | Basic | Add/Remove/Replace middle | ✅ Yes | Array of removed items |
.sort() | Advanced | Sort items | ✅ Yes | The sorted array |
.reverse() | Basic | Reverse order | ✅ Yes | The reversed array |
.map() | Advanced | Transform every item | ❌ No | New Array (Same Length) |
.filter() | Advanced | Select specific items | ❌ No | New Array (Subset) |
.reduce() | Advanced | Calculate single value | ❌ No | Single Value (Sum, Obj, etc) |
.concat() | Basic | Merge arrays | ❌ No | New Combined Array |
.slice() | Basic | Copy a portion | ❌ No | New Array Copy |
.join() | Basic | Convert to String | ❌ No | String |
.find() | Advanced | Find an item by logic | ❌ No | The Item (or undefined) |
.findIndex() | Advanced | Find index by logic | ❌ No | Index Number (or -1) |
.indexOf() | Basic | Find index by value | ❌ No | Index Number (or -1) |
.includes() | Basic | Check existence | ❌ No | Boolean (true/false) |
.some() | Advanced | Check if ANY match | ❌ No | Boolean (true/false) |
.every() | Advanced | Check if ALL match | ❌ No | Boolean (true/false) |
.forEach() | Advanced | Loop through items | ❌ No | undefined (Nothing) |
.length | Basic | Count of items | ❌ No | Number |
Why This Matters: In modern software engineering, the ability to efficiently manipulate data with array methods is often what separates a working script from a scalable, professional application.




