javascript

examples

examples.js
/**
 * ========================================
 * 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!');
Examples - JavaScript Tutorial | DeepML