Array Methods

40 min read Intermediate

Master the powerful array methods that make JavaScript so expressive: map, filter, reduce, and many more functional programming tools.

Transforming with map()

The map() method creates a new array by calling a function on every element. It transforms each element and returns a new array of the same length.

JavaScript
// Basic map - double all numbers
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// Original array is unchanged
console.log(numbers); // [1, 2, 3, 4, 5]

// Map with objects
const users = [
    { name: "Alice", age: 25 },
    { name: "Bob", age: 30 },
    { name: "Charlie", age: 35 }
];

// Extract just names
const names = users.map(user => user.name);
console.log(names); // ["Alice", "Bob", "Charlie"]

// Transform objects
const userCards = users.map(user => ({
    displayName: user.name.toUpperCase(),
    isAdult: user.age >= 18,
    birthYear: 2024 - user.age
}));
console.log(userCards);
// [
//   { displayName: "ALICE", isAdult: true, birthYear: 1999 },
//   { displayName: "BOB", isAdult: true, birthYear: 1994 },
//   { displayName: "CHARLIE", isAdult: true, birthYear: 1989 }
// ]

// Using index parameter
const indexed = ["a", "b", "c"].map((item, index) => `${index}: ${item}`);
console.log(indexed); // ["0: a", "1: b", "2: c"]

// Chaining with other methods
const prices = [10.5, 20.75, 30.25];
const formattedPrices = prices
    .map(price => price * 1.1)  // Add 10% tax
    .map(price => price.toFixed(2))  // Format to 2 decimals
    .map(price => `$${price}`);  // Add currency symbol
console.log(formattedPrices); // ["$11.55", "$22.83", "$33.28"]

Filtering with filter()

The filter() method creates a new array with elements that pass a test. Only elements for which the callback returns true are included.

JavaScript
// Basic filter - keep even numbers
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4, 6, 8, 10]

// Filter objects
const products = [
    { name: "Laptop", price: 999, inStock: true },
    { name: "Phone", price: 699, inStock: false },
    { name: "Tablet", price: 499, inStock: true },
    { name: "Watch", price: 299, inStock: true }
];

// Products in stock
const available = products.filter(p => p.inStock);
console.log(available.map(p => p.name)); // ["Laptop", "Tablet", "Watch"]

// Products under $500
const affordable = products.filter(p => p.price < 500);
console.log(affordable.map(p => p.name)); // ["Tablet", "Watch"]

// Multiple conditions
const goodDeals = products.filter(p => p.price < 500 && p.inStock);
console.log(goodDeals); // [{ name: "Tablet"... }, { name: "Watch"... }]

// Remove falsy values
const mixed = [0, 1, "", "hello", null, undefined, false, true];
const truthy = mixed.filter(Boolean);
console.log(truthy); // [1, "hello", true]

// Remove duplicates (works for primitives)
const duplicates = [1, 2, 2, 3, 3, 3, 4];
const unique = duplicates.filter((item, index, arr) => arr.indexOf(item) === index);
console.log(unique); // [1, 2, 3, 4]

// Better: use Set for unique values
const uniqueSet = [...new Set(duplicates)];
console.log(uniqueSet); // [1, 2, 3, 4]

// Search/filter text
const fruits = ["Apple", "Banana", "Apricot", "Orange", "Avocado"];
const startsWithA = fruits.filter(f => f.startsWith("A"));
console.log(startsWithA); // ["Apple", "Apricot", "Avocado"]

const containsAn = fruits.filter(f => f.toLowerCase().includes("an"));
console.log(containsAn); // ["Banana", "Orange"]

Reducing with reduce()

The reduce() method reduces an array to a single value by applying a function that accumulates results. It's the most versatile array method.

JavaScript
// Sum of numbers
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, current) => {
    return accumulator + current;
}, 0);  // 0 is the initial value
console.log(sum); // 15

// Shorter syntax
const total = numbers.reduce((acc, cur) => acc + cur, 0);
console.log(total); // 15

// Product of numbers
const product = numbers.reduce((acc, cur) => acc * cur, 1);
console.log(product); // 120

// Find maximum
const max = numbers.reduce((acc, cur) => cur > acc ? cur : acc);
console.log(max); // 5

// Count occurrences
const fruits = ["apple", "banana", "apple", "orange", "banana", "apple"];
const count = fruits.reduce((acc, fruit) => {
    acc[fruit] = (acc[fruit] || 0) + 1;
    return acc;
}, {});
console.log(count); // { apple: 3, banana: 2, orange: 1 }

// Group by property
const people = [
    { name: "Alice", department: "Engineering" },
    { name: "Bob", department: "Marketing" },
    { name: "Charlie", department: "Engineering" },
    { name: "Diana", department: "Marketing" }
];

const byDepartment = people.reduce((acc, person) => {
    const dept = person.department;
    if (!acc[dept]) acc[dept] = [];
    acc[dept].push(person);
    return acc;
}, {});
console.log(byDepartment);
// {
//   Engineering: [{ name: "Alice"... }, { name: "Charlie"... }],
//   Marketing: [{ name: "Bob"... }, { name: "Diana"... }]
// }

// Flatten nested arrays
const nested = [[1, 2], [3, 4], [5, 6]];
const flat = nested.reduce((acc, arr) => acc.concat(arr), []);
console.log(flat); // [1, 2, 3, 4, 5, 6]

// Or use flat() method
console.log(nested.flat()); // [1, 2, 3, 4, 5, 6]

// Pipeline of functions
const pipeline = [
    (x) => x + 1,
    (x) => x * 2,
    (x) => x - 3
];

const result = pipeline.reduce((acc, fn) => fn(acc), 5);
console.log(result); // ((5 + 1) * 2) - 3 = 9
Always Provide Initial Value

It's best practice to always provide an initial value to reduce(). Without it, the first element becomes the initial accumulator, which can cause errors with empty arrays.

Finding Elements

Several methods help you find elements or check if elements exist in an array.

JavaScript
const users = [
    { id: 1, name: "Alice", age: 25, active: true },
    { id: 2, name: "Bob", age: 30, active: false },
    { id: 3, name: "Charlie", age: 35, active: true },
    { id: 4, name: "Diana", age: 28, active: true }
];

// find() - returns first matching element
const alice = users.find(user => user.name === "Alice");
console.log(alice); // { id: 1, name: "Alice", age: 25, active: true }

const over30 = users.find(user => user.age > 30);
console.log(over30); // { id: 3, name: "Charlie"... }

// Returns undefined if not found
const notFound = users.find(user => user.name === "Eve");
console.log(notFound); // undefined

// findIndex() - returns index of first match
const bobIndex = users.findIndex(user => user.name === "Bob");
console.log(bobIndex); // 1

// findLast() & findLastIndex() (ES2023)
const numbers = [1, 5, 10, 15, 20, 25];
console.log(numbers.findLast(n => n > 10));      // 25
console.log(numbers.findLastIndex(n => n > 10)); // 5

// some() - returns true if ANY element passes test
const hasInactive = users.some(user => !user.active);
console.log(hasInactive); // true

const hasUnder18 = users.some(user => user.age < 18);
console.log(hasUnder18); // false

// every() - returns true if ALL elements pass test
const allActive = users.every(user => user.active);
console.log(allActive); // false

const allAdults = users.every(user => user.age >= 18);
console.log(allAdults); // true

// includes() - check if primitive exists
const fruits = ["apple", "banana", "orange"];
console.log(fruits.includes("banana")); // true
console.log(fruits.includes("grape"));  // false

// indexOf() and lastIndexOf()
const letters = ["a", "b", "c", "b", "d"];
console.log(letters.indexOf("b"));     // 1
console.log(letters.lastIndexOf("b")); // 3
console.log(letters.indexOf("z"));     // -1 (not found)

Sorting Arrays

The sort() method sorts elements in place. Without a compare function, it converts elements to strings and sorts alphabetically.

JavaScript
// String sorting (default)
const fruits = ["banana", "Apple", "cherry", "date"];
fruits.sort();
console.log(fruits); // ["Apple", "banana", "cherry", "date"]
// Note: uppercase comes before lowercase!

// Case-insensitive sorting
fruits.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
console.log(fruits); // ["Apple", "banana", "cherry", "date"]

// Number sorting - MUST use compare function!
const numbers = [10, 2, 5, 1, 9, 23];

// Wrong - sorts as strings!
numbers.sort();
console.log(numbers); // [1, 10, 2, 23, 5, 9]

// Correct - ascending
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 2, 5, 9, 10, 23]

// Descending
numbers.sort((a, b) => b - a);
console.log(numbers); // [23, 10, 9, 5, 2, 1]

// Sorting objects
const products = [
    { name: "Laptop", price: 999 },
    { name: "Phone", price: 699 },
    { name: "Tablet", price: 499 }
];

// Sort by price ascending
products.sort((a, b) => a.price - b.price);
console.log(products.map(p => p.name)); // ["Tablet", "Phone", "Laptop"]

// Sort by name
products.sort((a, b) => a.name.localeCompare(b.name));
console.log(products.map(p => p.name)); // ["Laptop", "Phone", "Tablet"]

// Multiple sort criteria
const people = [
    { name: "Alice", age: 30 },
    { name: "Bob", age: 25 },
    { name: "Alice", age: 25 }
];

// Sort by name, then by age
people.sort((a, b) => {
    if (a.name !== b.name) {
        return a.name.localeCompare(b.name);
    }
    return a.age - b.age;
});
console.log(people);
// [{ name: "Alice", age: 25 }, { name: "Alice", age: 30 }, { name: "Bob", age: 25 }]

// toSorted() - non-mutating sort (ES2023)
const original = [3, 1, 4, 1, 5];
const sorted = original.toSorted((a, b) => a - b);
console.log(original); // [3, 1, 4, 1, 5] - unchanged
console.log(sorted);   // [1, 1, 3, 4, 5]
Sort Mutates!

sort() modifies the original array. To avoid mutation, use toSorted() or create a copy first: [...arr].sort()

Flattening Arrays

Use flat() and flatMap() to work with nested arrays.

JavaScript
// flat() - flatten nested arrays
const nested = [1, [2, 3], [4, [5, 6]]];

console.log(nested.flat());   // [1, 2, 3, 4, [5, 6]] - depth 1
console.log(nested.flat(2));  // [1, 2, 3, 4, 5, 6] - depth 2
console.log(nested.flat(Infinity)); // Flatten all levels

// flat() also removes empty slots
const sparse = [1, , 3, , 5];
console.log(sparse.flat()); // [1, 3, 5]

// flatMap() - map + flat in one step
const sentences = ["Hello World", "How are you"];
const words = sentences.flatMap(s => s.split(" "));
console.log(words); // ["Hello", "World", "How", "are", "you"]

// Equivalent to:
const wordsManual = sentences.map(s => s.split(" ")).flat();
console.log(wordsManual); // ["Hello", "World", "How", "are", "you"]

// Practical: expand items
const items = [
    { name: "A", tags: ["x", "y"] },
    { name: "B", tags: ["z"] }
];

const expanded = items.flatMap(item => 
    item.tags.map(tag => ({ name: item.name, tag }))
);
console.log(expanded);
// [
//   { name: "A", tag: "x" },
//   { name: "A", tag: "y" },
//   { name: "B", tag: "z" }
// ]

// Filter and map in one operation
const numbers = [1, 2, 3, 4, 5];
const doubledEvens = numbers.flatMap(n => 
    n % 2 === 0 ? [n * 2] : []
);
console.log(doubledEvens); // [4, 8]

Method Chaining

Array methods that return arrays can be chained together for powerful data transformations.

JavaScript
const products = [
    { name: "Laptop", price: 999, category: "Electronics", rating: 4.5 },
    { name: "Phone", price: 699, category: "Electronics", rating: 4.2 },
    { name: "Desk", price: 199, category: "Furniture", rating: 4.0 },
    { name: "Chair", price: 299, category: "Furniture", rating: 4.8 },
    { name: "Tablet", price: 499, category: "Electronics", rating: 3.9 },
    { name: "Lamp", price: 49, category: "Furniture", rating: 4.1 }
];

// Chain: filter → sort → map → slice
const topElectronics = products
    .filter(p => p.category === "Electronics") // Only electronics
    .filter(p => p.rating >= 4.0)              // Rating 4+
    .sort((a, b) => b.rating - a.rating)       // Sort by rating desc
    .map(p => `${p.name} (${p.rating}★)`)      // Format as strings
    .slice(0, 3);                              // Top 3

console.log(topElectronics);
// ["Laptop (4.5★)", "Phone (4.2★)"]

// Calculate statistics
const stats = products
    .filter(p => p.category === "Electronics")
    .reduce((acc, p) => ({
        count: acc.count + 1,
        total: acc.total + p.price,
        avgRating: (acc.avgRating * acc.count + p.rating) / (acc.count + 1)
    }), { count: 0, total: 0, avgRating: 0 });

console.log(stats);
// { count: 3, total: 2197, avgRating: 4.2 }

// Transform and group
const byCategory = products
    .map(p => ({ ...p, priceRange: p.price > 500 ? "High" : "Low" }))
    .reduce((acc, p) => {
        const key = p.category;
        acc[key] = acc[key] || [];
        acc[key].push(p.name);
        return acc;
    }, {});

console.log(byCategory);
// { Electronics: ["Laptop", "Phone", "Tablet"], Furniture: ["Desk", "Chair", "Lamp"] }

// Real-world example: process user data
const users = [
    { name: "Alice", email: "alice@test.com", orders: 5, totalSpent: 500 },
    { name: "Bob", email: "bob@test.com", orders: 12, totalSpent: 1200 },
    { name: "Charlie", email: "charlie@test.com", orders: 3, totalSpent: 150 },
    { name: "Diana", email: "diana@test.com", orders: 8, totalSpent: 800 }
];

const vipReport = users
    .filter(u => u.orders >= 5)
    .map(u => ({
        ...u,
        averageOrder: (u.totalSpent / u.orders).toFixed(2),
        tier: u.totalSpent >= 1000 ? "Gold" : "Silver"
    }))
    .sort((a, b) => b.totalSpent - a.totalSpent)
    .map(u => `${u.name} (${u.tier}): $${u.totalSpent} across ${u.orders} orders`);

console.log(vipReport);
// [
//   "Bob (Gold): $1200 across 12 orders",
//   "Diana (Silver): $800 across 8 orders",
//   "Alice (Silver): $500 across 5 orders"
// ]

Other Useful Methods

JavaScript
// forEach() - execute function for each element (no return)
const numbers = [1, 2, 3];
numbers.forEach((num, index) => {
    console.log(`Index ${index}: ${num}`);
});

// fill() - fill array with value
const arr = new Array(5).fill(0);
console.log(arr); // [0, 0, 0, 0, 0]

const partial = [1, 2, 3, 4, 5];
partial.fill(0, 2, 4); // Fill from index 2 to 4
console.log(partial); // [1, 2, 0, 0, 5]

// Array.from() - create array from iterable
const str = "hello";
console.log(Array.from(str)); // ["h", "e", "l", "l", "o"]

// With mapping function
console.log(Array.from({ length: 5 }, (_, i) => i * 2));
// [0, 2, 4, 6, 8]

// Array.of() - create array from arguments
console.log(Array.of(1, 2, 3)); // [1, 2, 3]
console.log(Array.of(7));       // [7] (not array of length 7)

// at() - access by index (supports negative)
const letters = ["a", "b", "c", "d", "e"];
console.log(letters.at(0));   // "a"
console.log(letters.at(-1));  // "e"
console.log(letters.at(-2));  // "d"

// with() - non-mutating index assignment (ES2023)
const original = [1, 2, 3, 4, 5];
const updated = original.with(2, 99);
console.log(original); // [1, 2, 3, 4, 5]
console.log(updated);  // [1, 2, 99, 4, 5]

// toReversed() - non-mutating reverse (ES2023)
const nums = [1, 2, 3];
console.log(nums.toReversed()); // [3, 2, 1]
console.log(nums);              // [1, 2, 3] unchanged

// toSpliced() - non-mutating splice (ES2023)
const items = ["a", "b", "c", "d"];
const spliced = items.toSpliced(1, 2, "x", "y");
console.log(items);   // ["a", "b", "c", "d"] unchanged
console.log(spliced); // ["a", "x", "y", "d"]

Advanced Method Chaining

Method chaining allows you to write expressive, readable code by combining multiple array operations. Here are patterns and best practices.

JavaScript
// Good: Readable multi-line chaining
const result = users
    .filter(user => user.isActive)
    .map(user => ({
        id: user.id,
        fullName: `${user.firstName} ${user.lastName}`,
        email: user.email.toLowerCase()
    }))
    .sort((a, b) => a.fullName.localeCompare(b.fullName))
    .slice(0, 10);

// Order matters! Filter early, sort late
// BAD: Sort all 1000 items, then filter to 10
const slow = hugeArray
    .sort((a, b) => a.score - b.score)
    .filter(item => item.category === "active")
    .slice(0, 10);

// GOOD: Filter first reduces work for sort
const fast = hugeArray
    .filter(item => item.category === "active")
    .sort((a, b) => a.score - b.score)
    .slice(0, 10);

// Combining filter + map with flatMap
const emails = users
    .filter(u => u.email)
    .map(u => u.email);

// More concise with flatMap
const emailsFlatMap = users.flatMap(u => 
    u.email ? [u.email] : []
);

// Processing nested data with method chains
const orders = [
    { id: 1, items: [{ name: "Book", price: 20 }, { name: "Pen", price: 5 }] },
    { id: 2, items: [{ name: "Laptop", price: 1000 }] },
    { id: 3, items: [{ name: "Mouse", price: 50 }, { name: "Keyboard", price: 100 }] }
];

const totalRevenue = orders
    .flatMap(order => order.items)
    .reduce((sum, item) => sum + item.price, 0);
console.log(totalRevenue); // 1175

// Creating lookup objects with reduce
const usersById = users.reduce((acc, user) => {
    acc[user.id] = user;
    return acc;
}, {});

// Grouping with reduce
const usersByRole = users.reduce((groups, user) => {
    const role = user.role;
    groups[role] = groups[role] || [];
    groups[role].push(user);
    return groups;
}, {});

// ES2024: Object.groupBy (when available)
// const grouped = Object.groupBy(users, user => user.role);

Array Performance Tips

Understanding performance characteristics helps you write efficient code, especially with large datasets.

JavaScript
// 1. Avoid multiple iterations when one will do
// BAD: 3 iterations
const result1 = numbers
    .filter(n => n > 0)
    .map(n => n * 2)
    .filter(n => n < 100);

// BETTER: 1 iteration with reduce
const result2 = numbers.reduce((acc, n) => {
    if (n > 0) {
        const doubled = n * 2;
        if (doubled < 100) {
            acc.push(doubled);
        }
    }
    return acc;
}, []);

// 2. For simple lookups, use Set instead of includes
const largeArray = [/* thousands of items */];

// SLOW: O(n) for each check
if (largeArray.includes(item)) { }

// FAST: O(1) for each check
const lookupSet = new Set(largeArray);
if (lookupSet.has(item)) { }

// 3. Pre-allocate array size when known
// SLOW: Array grows repeatedly
const arr1 = [];
for (let i = 0; i < 10000; i++) {
    arr1.push(i);
}

// FASTER: Single allocation
const arr2 = new Array(10000);
for (let i = 0; i < 10000; i++) {
    arr2[i] = i;
}

// 4. Use typed arrays for numeric operations
const regularArray = new Array(1000000).fill(0);
const typedArray = new Float64Array(1000000);
// typedArray operations are faster for math

// 5. Avoid creating functions in loops
// BAD: Creates new function on each iteration
array.forEach(item => {
    items.map(x => x * 2);  // New function each time!
});

// GOOD: Reuse function reference
const double = x => x * 2;
array.forEach(item => {
    items.map(double);
});

// 6. Use for loops for maximum performance
// When readability isn't a concern and speed matters:
let sum = 0;
for (let i = 0; i < array.length; i++) {
    sum += array[i];
}

// Method comparison (rough speed ranking):
// 1. for loop (fastest)
// 2. for...of
// 3. forEach
// 4. reduce
// 5. map/filter (create new arrays)

Performance Note

Don't prematurely optimize! For arrays under 1000 elements, the difference is negligible. Prioritize readable, maintainable code. Only optimize when profiling reveals actual bottlenecks.

flat() and flatMap() Deep Dive

These methods are powerful for working with nested arrays and combining mapping with flattening.

JavaScript
// flat() - flatten nested arrays
const nested = [1, [2, 3], [4, [5, 6]]];
console.log(nested.flat());     // [1, 2, 3, 4, [5, 6]]
console.log(nested.flat(2));    // [1, 2, 3, 4, 5, 6]
console.log(nested.flat(Infinity)); // Flatten all levels

// Removing empty slots
const sparse = [1, , 3, , 5];
console.log(sparse.flat()); // [1, 3, 5]

// flatMap() - map then flat(1)
const sentences = ["Hello world", "How are you"];
const words = sentences.flatMap(s => s.split(" "));
console.log(words); // ["Hello", "world", "How", "are", "you"]

// vs map().flat()
const wordsSame = sentences.map(s => s.split(" ")).flat();
// Same result, but flatMap is more efficient

// Filter and transform in one step
const data = [
    { name: "Alice", tags: ["js", "react"] },
    { name: "Bob", tags: [] },
    { name: "Charlie", tags: ["python", "ml"] }
];

// Get all tags (skip empty)
const allTags = data.flatMap(person => person.tags);
console.log(allTags); // ["js", "react", "python", "ml"]

// Filter with flatMap (return [] to exclude)
const numbers = [1, 2, 3, 4, 5, 6];
const doubledEvens = numbers.flatMap(n => 
    n % 2 === 0 ? [n * 2] : []
);
console.log(doubledEvens); // [4, 8, 12]

// Expand items conditionally
const items = [
    { type: "single", value: 1 },
    { type: "triple", value: 2 },
    { type: "single", value: 3 }
];

const expanded = items.flatMap(item => 
    item.type === "triple" 
        ? [item.value, item.value, item.value]
        : [item.value]
);
console.log(expanded); // [1, 2, 2, 2, 3]

// Parse and flatten in one step
const csvRows = ["1,2,3", "4,5,6", "7,8,9"];
const allNumbers = csvRows.flatMap(row => 
    row.split(",").map(Number)
);
console.log(allNumbers); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

// Create pairs/combinations
const colors = ["red", "blue"];
const sizes = ["S", "M", "L"];

const combinations = colors.flatMap(color =>
    sizes.map(size => `${color}-${size}`)
);
console.log(combinations);
// ["red-S", "red-M", "red-L", "blue-S", "blue-M", "blue-L"]

Polyfills and Compatibility

Some array methods are newer and may not be available in older environments. Here's how to handle that.

JavaScript
// Array method browser support (as of 2024):
// ES5 (IE9+): forEach, map, filter, reduce, every, some, indexOf
// ES6 (2015): find, findIndex, includes, fill, from, of
// ES2019: flat, flatMap
// ES2022: at, findLast, findLastIndex
// ES2023: toReversed, toSorted, toSpliced, with

// Polyfill for Array.prototype.at
if (!Array.prototype.at) {
    Array.prototype.at = function(index) {
        const len = this.length;
        const relativeIndex = index >= 0 ? index : len + index;
        
        if (relativeIndex < 0 || relativeIndex >= len) {
            return undefined;
        }
        
        return this[relativeIndex];
    };
}

// Polyfill for flat
if (!Array.prototype.flat) {
    Array.prototype.flat = function(depth = 1) {
        return depth > 0
            ? this.reduce((acc, val) => 
                acc.concat(Array.isArray(val) ? val.flat(depth - 1) : val), [])
            : this.slice();
    };
}

// Polyfill for flatMap
if (!Array.prototype.flatMap) {
    Array.prototype.flatMap = function(callback) {
        return this.map(callback).flat();
    };
}

// Feature detection pattern
function safeAt(array, index) {
    if (typeof array.at === 'function') {
        return array.at(index);
    }
    // Fallback
    return index >= 0 ? array[index] : array[array.length + index];
}

// Using core-js for comprehensive polyfills
// npm install core-js
// import 'core-js/actual/array/at';
// import 'core-js/actual/array/flat';
// import 'core-js/actual/array/flat-map';

// Check what needs polyfilling
const unsupportedMethods = [
    'at', 'flat', 'flatMap', 'findLast', 'findLastIndex',
    'toReversed', 'toSorted', 'toSpliced', 'with'
].filter(method => !(method in Array.prototype));

console.log('Needs polyfill:', unsupportedMethods);

Recommended Approach

For production applications:

  • Use Babel with @babel/preset-env for transpilation
  • Use core-js for polyfills based on your browser targets
  • Configure browserslist in package.json to specify target browsers
  • Consider bundler plugins that automatically inject only needed polyfills

Summary

map()

Transform each element, returns new array of same length

filter()

Keep elements passing a test, returns subset

reduce()

Accumulate to single value (sum, object, etc.)

find() / findIndex()

Find first matching element or its index

some() / every()

Check if any/all elements pass a test

sort()

Sort in place (use compare fn for numbers!)