javascript
examples
examples.js⚡javascript
/**
* ========================================
* 12.2 Key Array Methods - Examples
* ========================================
*
* Deep dive into essential array methods.
*/
/**
* EXAMPLE 1: map() - Transform Every Element
*
* Creates a new array by applying function to each element.
*/
// Basic transformation
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((n) => n * 2);
console.log('Doubled:', doubled); // [2, 4, 6, 8, 10]
const squared = numbers.map((n) => n ** 2);
console.log('Squared:', squared); // [1, 4, 9, 16, 25]
// With index
const indexed = numbers.map((n, i) => `${i}: ${n}`);
console.log('Indexed:', indexed);
// Transform objects
const users = [
{ firstName: 'John', lastName: 'Doe' },
{ firstName: 'Jane', lastName: 'Smith' },
];
const fullNames = users.map((u) => `${u.firstName} ${u.lastName}`);
console.log('Full names:', fullNames);
const enhanced = users.map((u) => ({
...u,
fullName: `${u.firstName} ${u.lastName}`,
initials: `${u.firstName[0]}${u.lastName[0]}`,
}));
console.log('Enhanced:', enhanced);
/**
* EXAMPLE 2: filter() - Select Elements
*
* Creates array with elements that pass test.
*/
const allNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Filter by condition
const evens = allNumbers.filter((n) => n % 2 === 0);
console.log('Evens:', evens); // [2, 4, 6, 8, 10]
const odds = allNumbers.filter((n) => n % 2 !== 0);
console.log('Odds:', odds); // [1, 3, 5, 7, 9]
const greaterThan5 = allNumbers.filter((n) => n > 5);
console.log('Greater than 5:', greaterThan5);
// Filter objects
const products = [
{ name: 'Laptop', price: 999, inStock: true, category: 'electronics' },
{ name: 'Phone', price: 699, inStock: false, category: 'electronics' },
{ name: 'Shirt', price: 49, inStock: true, category: 'clothing' },
{ name: 'Book', price: 29, inStock: true, category: 'books' },
];
const available = products.filter((p) => p.inStock);
console.log(
'Available:',
available.map((p) => p.name)
);
const affordable = products.filter((p) => p.price < 100);
console.log(
'Under $100:',
affordable.map((p) => p.name)
);
const electronics = products.filter((p) => p.category === 'electronics');
console.log(
'Electronics:',
electronics.map((p) => p.name)
);
/**
* EXAMPLE 3: reduce() - Aggregate to Single Value
*
* The most powerful array method.
*/
// Sum
const nums = [1, 2, 3, 4, 5];
const sum = nums.reduce((acc, n) => acc + n, 0);
console.log('Sum:', sum); // 15
// Product
const product = nums.reduce((acc, n) => acc * n, 1);
console.log('Product:', product); // 120
// Max (without initial value, uses first element)
const max = nums.reduce((a, b) => Math.max(a, b));
console.log('Max:', max); // 5
// Min
const min = nums.reduce((a, b) => Math.min(a, b));
console.log('Min:', min); // 1
// Average
const avg = nums.reduce((acc, n, i, arr) => {
acc += n;
if (i === arr.length - 1) return acc / arr.length;
return acc;
}, 0);
console.log('Average:', avg); // 3
/**
* EXAMPLE 4: reduce() - Complex Aggregations
*/
// Count occurrences
const fruits = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple'];
const fruitCounts = fruits.reduce((acc, fruit) => {
acc[fruit] = (acc[fruit] || 0) + 1;
return acc;
}, {});
console.log('Fruit counts:', fruitCounts);
// { apple: 3, banana: 2, cherry: 1 }
// Group by property
const people = [
{ name: 'John', department: 'Sales' },
{ name: 'Jane', department: 'Engineering' },
{ name: 'Bob', department: 'Sales' },
{ name: 'Alice', department: 'Engineering' },
{ name: 'Charlie', department: 'Marketing' },
];
const byDepartment = people.reduce((acc, person) => {
const dept = person.department;
acc[dept] = acc[dept] || [];
acc[dept].push(person);
return acc;
}, {});
console.log('By department:', byDepartment);
// Flatten arrays
const nested = [
[1, 2],
[3, 4],
[5, 6],
];
const flat = nested.reduce((acc, arr) => acc.concat(arr), []);
console.log('Flattened:', flat); // [1, 2, 3, 4, 5, 6]
// Build object from entries
const entries = [
['a', 1],
['b', 2],
['c', 3],
];
const obj = entries.reduce((acc, [key, value]) => {
acc[key] = value;
return acc;
}, {});
console.log('Object:', obj); // { a: 1, b: 2, c: 3 }
/**
* EXAMPLE 5: find() and findIndex()
*/
const inventory = [
{ id: 1, name: 'Apple', price: 1.5, quantity: 50 },
{ id: 2, name: 'Banana', price: 0.75, quantity: 0 },
{ id: 3, name: 'Cherry', price: 2.0, quantity: 30 },
{ id: 4, name: 'Date', price: 3.0, quantity: 15 },
];
// find - returns first match
const banana = inventory.find((item) => item.name === 'Banana');
console.log('Found:', banana);
const outOfStock = inventory.find((item) => item.quantity === 0);
console.log('Out of stock:', outOfStock?.name);
const expensive = inventory.find((item) => item.price > 2);
console.log('First expensive:', expensive?.name);
// findIndex - returns index
const cherryIndex = inventory.findIndex((item) => item.name === 'Cherry');
console.log('Cherry index:', cherryIndex); // 2
// Not found returns undefined (find) or -1 (findIndex)
const grape = inventory.find((item) => item.name === 'Grape');
console.log('Grape:', grape); // undefined
const grapeIndex = inventory.findIndex((item) => item.name === 'Grape');
console.log('Grape index:', grapeIndex); // -1
/**
* EXAMPLE 6: findLast() and findLastIndex() (ES2023)
*/
const transactions = [
{ type: 'deposit', amount: 100 },
{ type: 'withdrawal', amount: 50 },
{ type: 'deposit', amount: 200 },
{ type: 'withdrawal', amount: 75 },
];
// Find last deposit
const lastDeposit = transactions.findLast((t) => t.type === 'deposit');
console.log('Last deposit:', lastDeposit); // { type: 'deposit', amount: 200 }
// Find last deposit index
const lastDepositIndex = transactions.findLastIndex(
(t) => t.type === 'deposit'
);
console.log('Last deposit index:', lastDepositIndex); // 2
/**
* EXAMPLE 7: every() and some()
*/
const scores = [85, 92, 78, 95, 88];
// every - all must pass
console.log(
'All passing (>70):',
scores.every((s) => s >= 70)
); // true
console.log(
'All excellent (>90):',
scores.every((s) => s >= 90)
); // false
// some - at least one must pass
console.log(
'Any excellent:',
scores.some((s) => s >= 90)
); // true
console.log(
'Any failing:',
scores.some((s) => s < 70)
); // false
// Practical validation
const formData = [
{ field: 'name', value: 'John' },
{ field: 'email', value: 'john@example.com' },
{ field: 'age', value: 30 },
];
const allFilled = formData.every((f) => f.value !== '' && f.value !== null);
console.log('All fields filled:', allFilled);
const hasEmpty = formData.some((f) => f.value === '' || f.value === null);
console.log('Has empty fields:', hasEmpty);
// Early termination demo
const largeArray = Array.from({ length: 1000000 }, (_, i) => i);
console.time('some');
largeArray.some((n) => n === 5); // Stops at index 5
console.timeEnd('some');
console.time('find');
largeArray.find((n) => n === 5); // Also stops at index 5
console.timeEnd('find');
/**
* EXAMPLE 8: flat() and flatMap()
*/
// flat - flatten nested arrays
const nestedArr = [1, [2, 3], [4, [5, 6]], [[7]]];
console.log('flat():', nestedArr.flat());
// [1, 2, 3, 4, [5, 6], [7]]
console.log('flat(2):', nestedArr.flat(2));
// [1, 2, 3, 4, 5, 6, 7]
console.log('flat(Infinity):', nestedArr.flat(Infinity));
// [1, 2, 3, 4, 5, 6, 7]
// Remove holes
const sparse = [1, , 3, , 5];
console.log('Remove holes:', sparse.flat()); // [1, 3, 5]
// flatMap - map + flat(1)
const sentences = ['Hello World', 'How are you'];
const words = sentences.flatMap((s) => s.split(' '));
console.log('Words:', words);
// ['Hello', 'World', 'How', 'are', 'you']
// Expand items conditionally
const numbersToExpand = [1, 2, 3, 4];
const expanded = numbersToExpand.flatMap((n) =>
n % 2 === 0 ? [n, n * 10] : [n]
);
console.log('Expanded evens:', expanded);
// [1, 2, 20, 3, 4, 40]
/**
* EXAMPLE 9: ES2023 Non-Mutating Methods
*/
const original = [3, 1, 4, 1, 5, 9, 2, 6];
// toSorted - doesn't mutate
const sorted = original.toSorted((a, b) => a - b);
console.log('Sorted:', sorted);
console.log('Original unchanged:', original);
// toReversed - doesn't mutate
const reversed = original.toReversed();
console.log('Reversed:', reversed);
console.log('Original unchanged:', original);
// toSpliced - doesn't mutate
const spliced = original.toSpliced(2, 2, 'a', 'b');
console.log('Spliced:', spliced);
console.log('Original unchanged:', original);
// with - doesn't mutate
const updated = original.with(0, 100);
console.log('With:', updated);
console.log('Original unchanged:', original);
// Chaining ES2023 methods
const result = original
.toSorted((a, b) => a - b)
.toReversed()
.with(0, 99);
console.log('Chained:', result);
/**
* EXAMPLE 10: Sorting In Depth
*/
// Default sort (alphabetical/string)
const numericDefault = [10, 2, 30, 1, 20];
console.log('Default sort:', [...numericDefault].sort());
// [1, 10, 2, 20, 30] - Wrong for numbers!
// Numeric ascending
console.log(
'Ascending:',
[...numericDefault].sort((a, b) => a - b)
);
// [1, 2, 10, 20, 30]
// Numeric descending
console.log(
'Descending:',
[...numericDefault].sort((a, b) => b - a)
);
// [30, 20, 10, 2, 1]
// String sort (case-insensitive)
const mixedCase = ['Banana', 'apple', 'Cherry', 'date'];
console.log(
'Case-insensitive:',
[...mixedCase].sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
);
// Object sort - single property
const employees = [
{ name: 'John', age: 30, salary: 50000 },
{ name: 'Jane', age: 25, salary: 60000 },
{ name: 'Bob', age: 35, salary: 55000 },
];
// By age
const byAge = [...employees].sort((a, b) => a.age - b.age);
console.log(
'By age:',
byAge.map((e) => e.name)
);
// By salary descending
const bySalary = [...employees].sort((a, b) => b.salary - a.salary);
console.log(
'By salary (desc):',
bySalary.map((e) => e.name)
);
// By name
const byName = [...employees].sort((a, b) => a.name.localeCompare(b.name));
console.log(
'By name:',
byName.map((e) => e.name)
);
/**
* EXAMPLE 11: Multi-Criteria Sorting
*/
const students = [
{ name: 'Alice', grade: 'A', score: 95 },
{ name: 'Bob', grade: 'B', score: 85 },
{ name: 'Charlie', grade: 'A', score: 92 },
{ name: 'Diana', grade: 'B', score: 88 },
{ name: 'Eve', grade: 'A', score: 95 },
];
// Sort by grade, then by score descending, then by name
const multiSort = [...students].sort((a, b) => {
// First: grade ascending
if (a.grade !== b.grade) {
return a.grade.localeCompare(b.grade);
}
// Second: score descending
if (a.score !== b.score) {
return b.score - a.score;
}
// Third: name ascending
return a.name.localeCompare(b.name);
});
console.log(
'Multi-sort:',
multiSort.map((s) => `${s.name} (${s.grade}:${s.score})`)
);
/**
* EXAMPLE 12: includes(), indexOf(), lastIndexOf()
*/
const arr = [1, 2, 3, 4, 5, 3, 2, 1];
// includes - check existence
console.log('Includes 3:', arr.includes(3)); // true
console.log('Includes 10:', arr.includes(10)); // false
console.log('Includes 3 from index 5:', arr.includes(3, 5)); // true
// indexOf - find first index
console.log('Index of 3:', arr.indexOf(3)); // 2
console.log('Index of 10:', arr.indexOf(10)); // -1
console.log('Index of 3 from 3:', arr.indexOf(3, 3)); // 5
// lastIndexOf - find last index
console.log('Last index of 3:', arr.lastIndexOf(3)); // 5
console.log('Last index of 2:', arr.lastIndexOf(2)); // 6
// NaN handling
const withNaN = [1, NaN, 2, NaN];
console.log('indexOf NaN:', withNaN.indexOf(NaN)); // -1 (doesn't work!)
console.log('includes NaN:', withNaN.includes(NaN)); // true (works!)
console.log(
'findIndex NaN:',
withNaN.findIndex((n) => Number.isNaN(n))
); // 1
/**
* EXAMPLE 13: concat() and join()
*/
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// concat - combine arrays
const combined = arr1.concat(arr2);
console.log('Combined:', combined); // [1, 2, 3, 4, 5, 6]
const multiConcat = arr1.concat(arr2, [7, 8], 9);
console.log('Multi:', multiConcat); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
// concat doesn't flatten nested
const withNested = arr1.concat([[4, 5]]);
console.log('With nested:', withNested); // [1, 2, 3, [4, 5]]
// join - array to string
const wordsArr = ['Hello', 'World'];
console.log('Space join:', wordsArr.join(' ')); // 'Hello World'
console.log('Dash join:', wordsArr.join('-')); // 'Hello-World'
console.log('No sep:', wordsArr.join('')); // 'HelloWorld'
console.log('Default:', wordsArr.join()); // 'Hello,World'
// Practical: build paths
const pathParts = ['home', 'user', 'documents', 'file.txt'];
console.log('Path:', pathParts.join('/')); // home/user/documents/file.txt
/**
* EXAMPLE 14: Method Chaining
*/
const orders = [
{ id: 1, customer: 'John', items: 3, total: 150, status: 'completed' },
{ id: 2, customer: 'Jane', items: 1, total: 50, status: 'pending' },
{ id: 3, customer: 'Bob', items: 5, total: 300, status: 'completed' },
{ id: 4, customer: 'Alice', items: 2, total: 100, status: 'cancelled' },
{ id: 5, customer: 'Charlie', items: 4, total: 250, status: 'completed' },
];
// Chain to analyze completed orders
const analysis = orders
.filter((o) => o.status === 'completed') // Only completed
.map((o) => ({
// Transform
customer: o.customer,
total: o.total,
avgPerItem: o.total / o.items,
}))
.sort((a, b) => b.total - a.total); // Sort by total
console.log('Completed orders analysis:', analysis);
// Calculate totals with reduce at end
const completedStats = orders
.filter((o) => o.status === 'completed')
.reduce(
(acc, order) => ({
count: acc.count + 1,
totalRevenue: acc.totalRevenue + order.total,
totalItems: acc.totalItems + order.items,
}),
{ count: 0, totalRevenue: 0, totalItems: 0 }
);
console.log('Completed stats:', completedStats);
/**
* EXAMPLE 15: entries(), keys(), values()
*/
const colors = ['red', 'green', 'blue'];
// entries - [index, value] pairs
console.log('Entries:');
for (const [index, color] of colors.entries()) {
console.log(` ${index}: ${color}`);
}
// Convert to array
const entriesArray = [...colors.entries()];
console.log('Entries array:', entriesArray);
// [[0, 'red'], [1, 'green'], [2, 'blue']]
// keys - indices
console.log('Keys:', [...colors.keys()]); // [0, 1, 2]
// values - elements
console.log('Values:', [...colors.values()]); // ['red', 'green', 'blue']
/**
* EXAMPLE 16: copyWithin() and fill()
*/
// copyWithin - copy within array
const copyArr = [1, 2, 3, 4, 5];
copyArr.copyWithin(0, 3); // Copy from index 3 to index 0
console.log('copyWithin(0, 3):', copyArr); // [4, 5, 3, 4, 5]
const copyArr2 = [1, 2, 3, 4, 5];
copyArr2.copyWithin(1, 3, 4); // Copy index 3-4 to index 1
console.log('copyWithin(1, 3, 4):', copyArr2); // [1, 4, 3, 4, 5]
// fill - fill with value
const fillArr = [1, 2, 3, 4, 5];
fillArr.fill(0);
console.log('fill(0):', fillArr); // [0, 0, 0, 0, 0]
const fillArr2 = [1, 2, 3, 4, 5];
fillArr2.fill(0, 1, 4); // Fill indices 1-3
console.log('fill(0, 1, 4):', fillArr2); // [1, 0, 0, 0, 5]
// Create array filled with value
const zeros = new Array(5).fill(0);
console.log('Array of zeros:', zeros);
// ⚠️ fill with objects shares reference
const objArray = new Array(3).fill({});
objArray[0].name = 'Changed';
console.log('Shared reference:', objArray);
// [{name:'Changed'}, {name:'Changed'}, {name:'Changed'}]
// Correct way for independent objects
const independentObjs = Array.from({ length: 3 }, () => ({}));
independentObjs[0].name = 'Changed';
console.log('Independent:', independentObjs);
/**
* EXAMPLE 17: Performance Comparison
*/
// Single reduce vs multiple methods
const data = Array.from({ length: 10000 }, (_, i) => ({
value: Math.random() * 100,
active: Math.random() > 0.5,
}));
// Approach 1: Chained methods (multiple passes)
console.time('Chained');
const result1 = data
.filter((d) => d.active)
.map((d) => d.value)
.reduce((sum, v) => sum + v, 0);
console.timeEnd('Chained');
// Approach 2: Single reduce (one pass)
console.time('Single reduce');
const result2 = data.reduce((sum, d) => (d.active ? sum + d.value : sum), 0);
console.timeEnd('Single reduce');
console.log('Same result:', result1 === result2);
console.log('\nKey array methods examples completed!');