javascript
examples
examples.js⚡javascript
/**
* =====================================================
* 5.7 HIGHER-ORDER FUNCTIONS - EXAMPLES
* =====================================================
* Functions that take or return functions
*/
// =====================================================
// 1. FUNCTIONS AS ARGUMENTS
// =====================================================
console.log('--- Functions as Arguments ---');
function repeat(n, action) {
for (let i = 0; i < n; i++) {
action(i);
}
}
console.log('Repeat 3 times:');
repeat(3, (i) => console.log(` Iteration ${i}`));
// Custom array processor
function processArray(arr, operation) {
const result = [];
for (const item of arr) {
result.push(operation(item));
}
return result;
}
const numbers = [1, 2, 3, 4, 5];
console.log(
'Doubled:',
processArray(numbers, (n) => n * 2)
);
console.log(
'Squared:',
processArray(numbers, (n) => n * n)
);
// =====================================================
// 2. FUNCTIONS AS RETURN VALUES
// =====================================================
console.log('\n--- Functions as Return Values ---');
function createMultiplier(factor) {
return function (number) {
return number * factor;
};
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
const quadruple = createMultiplier(4);
console.log('double(5):', double(5)); // 10
console.log('triple(5):', triple(5)); // 15
console.log('quadruple(5):', quadruple(5)); // 20
// =====================================================
// 3. MAP() - TRANSFORM EACH ELEMENT
// =====================================================
console.log('\n--- map() ---');
const nums = [1, 2, 3, 4, 5];
// Basic transformation
const doubled = nums.map((n) => n * 2);
console.log('Doubled:', doubled);
// Object transformation
const users = [
{ firstName: 'Alice', lastName: 'Smith' },
{ firstName: 'Bob', lastName: 'Jones' },
{ firstName: 'Charlie', lastName: 'Brown' },
];
const fullNames = users.map((u) => `${u.firstName} ${u.lastName}`);
console.log('Full names:', fullNames);
// With index
const indexed = nums.map((n, i) => ({ index: i, value: n }));
console.log('Indexed:', indexed);
// =====================================================
// 4. FILTER() - SELECT MATCHING ELEMENTS
// =====================================================
console.log('\n--- filter() ---');
const allNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Even numbers
const evens = allNumbers.filter((n) => n % 2 === 0);
console.log('Evens:', evens);
// Greater than 5
const large = allNumbers.filter((n) => n > 5);
console.log('Greater than 5:', large);
// Filter objects
const products = [
{ name: 'Apple', price: 1.5, inStock: true },
{ name: 'Banana', price: 0.75, inStock: false },
{ name: 'Orange', price: 2.0, inStock: true },
];
const available = products.filter((p) => p.inStock);
console.log('In stock:', available);
const affordable = products.filter((p) => p.price < 2);
console.log('Under $2:', affordable);
// =====================================================
// 5. REDUCE() - COMBINE INTO SINGLE VALUE
// =====================================================
console.log('\n--- reduce() ---');
const values = [1, 2, 3, 4, 5];
// Sum
const sum = values.reduce((acc, n) => acc + n, 0);
console.log('Sum:', sum);
// Product
const product = values.reduce((acc, n) => acc * n, 1);
console.log('Product:', product);
// Max
const max = values.reduce((acc, n) => (n > acc ? n : acc), -Infinity);
console.log('Max:', max);
// Count occurrences
const letters = ['a', 'b', 'a', 'c', 'b', 'a', 'd'];
const counts = letters.reduce((acc, letter) => {
acc[letter] = (acc[letter] || 0) + 1;
return acc;
}, {});
console.log('Letter counts:', counts);
// Group by property
const people = [
{ name: 'Alice', department: 'Engineering' },
{ name: 'Bob', department: 'Sales' },
{ name: 'Charlie', department: 'Engineering' },
{ name: 'Diana', department: 'Sales' },
];
const byDept = people.reduce((acc, person) => {
const dept = person.department;
if (!acc[dept]) acc[dept] = [];
acc[dept].push(person.name);
return acc;
}, {});
console.log('By department:', byDept);
// =====================================================
// 6. FOREACH() - EXECUTE FOR EACH
// =====================================================
console.log('\n--- forEach() ---');
const items = ['apple', 'banana', 'cherry'];
// Logging
console.log('Items:');
items.forEach((item, index) => {
console.log(` ${index + 1}. ${item}`);
});
// Side effects
let totalLength = 0;
items.forEach((item) => {
totalLength += item.length;
});
console.log('Total length:', totalLength);
// =====================================================
// 7. FIND() AND FINDINDEX()
// =====================================================
console.log('\n--- find() and findIndex() ---');
const employees = [
{ id: 1, name: 'Alice', role: 'Developer' },
{ id: 2, name: 'Bob', role: 'Designer' },
{ id: 3, name: 'Charlie', role: 'Developer' },
];
// find() - returns element
const found = employees.find((e) => e.id === 2);
console.log('Found employee:', found);
// findIndex() - returns index
const index = employees.findIndex((e) => e.role === 'Designer');
console.log('Designer index:', index);
// First developer
const firstDev = employees.find((e) => e.role === 'Developer');
console.log('First developer:', firstDev);
// Not found
const notFound = employees.find((e) => e.id === 99);
console.log('Not found:', notFound); // undefined
// =====================================================
// 8. SOME() AND EVERY()
// =====================================================
console.log('\n--- some() and every() ---');
const scores = [75, 82, 93, 68, 85];
// some() - at least one
const hasHigh = scores.some((s) => s >= 90);
console.log('Has score >= 90:', hasHigh); // true
// every() - all
const allPassing = scores.every((s) => s >= 60);
console.log('All passing (>= 60):', allPassing); // true
const allExcellent = scores.every((s) => s >= 90);
console.log('All excellent (>= 90):', allExcellent); // false
// With objects
const tasks = [
{ name: 'Task 1', completed: true },
{ name: 'Task 2', completed: true },
{ name: 'Task 3', completed: false },
];
const allDone = tasks.every((t) => t.completed);
console.log('All tasks done:', allDone); // false
const anyDone = tasks.some((t) => t.completed);
console.log('Any task done:', anyDone); // true
// =====================================================
// 9. SORT()
// =====================================================
console.log('\n--- sort() ---');
// Number sorting (ascending)
const unsorted = [3, 1, 4, 1, 5, 9, 2, 6];
const ascending = [...unsorted].sort((a, b) => a - b);
console.log('Ascending:', ascending);
// Descending
const descending = [...unsorted].sort((a, b) => b - a);
console.log('Descending:', descending);
// String sorting
const names = ['Charlie', 'alice', 'Bob'];
const alphabetical = [...names].sort();
console.log('Alphabetical:', alphabetical);
// Case-insensitive
const caseInsensitive = [...names].sort((a, b) =>
a.toLowerCase().localeCompare(b.toLowerCase())
);
console.log('Case-insensitive:', caseInsensitive);
// Sort objects by property
const userList = [
{ name: 'Charlie', age: 35 },
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
];
const byAge = [...userList].sort((a, b) => a.age - b.age);
console.log(
'By age:',
byAge.map((u) => u.name)
);
const byName = [...userList].sort((a, b) => a.name.localeCompare(b.name));
console.log(
'By name:',
byName.map((u) => u.name)
);
// =====================================================
// 10. METHOD CHAINING
// =====================================================
console.log('\n--- Method Chaining ---');
const transactions = [
{ type: 'sale', amount: 100, date: '2024-01-15' },
{ type: 'refund', amount: -50, date: '2024-01-16' },
{ type: 'sale', amount: 200, date: '2024-01-17' },
{ type: 'sale', amount: 75, date: '2024-01-18' },
{ type: 'refund', amount: -25, date: '2024-01-19' },
];
// Total sales over $50
const bigSalesTotal = transactions
.filter((t) => t.type === 'sale')
.filter((t) => t.amount > 50)
.map((t) => t.amount)
.reduce((sum, a) => sum + a, 0);
console.log('Big sales total:', bigSalesTotal); // 300
// Format and display
const salesReport = transactions
.filter((t) => t.type === 'sale')
.map((t) => `$${t.amount} on ${t.date}`)
.join('\n');
console.log('Sales report:\n' + salesReport);
// =====================================================
// 11. FLATMAP()
// =====================================================
console.log('\n--- flatMap() ---');
const sentences = ['Hello world', 'JavaScript is fun'];
// Split into words (map + flat)
const words = sentences.flatMap((s) => s.split(' '));
console.log('Words:', words);
// Generate pairs
const pairs = [1, 2, 3].flatMap((n) => [n, n * 2]);
console.log('Pairs:', pairs);
// =====================================================
// 12. CUSTOM HIGHER-ORDER FUNCTIONS
// =====================================================
console.log('\n--- Custom Higher-Order Functions ---');
// Custom filter
function myFilter(arr, predicate) {
const result = [];
for (const item of arr) {
if (predicate(item)) {
result.push(item);
}
}
return result;
}
console.log(
'Custom filter:',
myFilter([1, 2, 3, 4], (n) => n % 2 === 0)
);
// Pipe function
function pipe(...fns) {
return function (value) {
return fns.reduce((acc, fn) => fn(acc), value);
};
}
const process = pipe(
(n) => n * 2, // 5 → 10
(n) => n + 3, // 10 → 13
(n) => n * n // 13 → 169
);
console.log('Pipe result:', process(5));
// Compose function (right to left)
function compose(...fns) {
return function (value) {
return fns.reduceRight((acc, fn) => fn(acc), value);
};
}
const calculate = compose(
(n) => n * n, // Last: square
(n) => n + 3, // Then: add 3
(n) => n * 2 // First: double
);
console.log('Compose result:', calculate(5)); // ((5 * 2) + 3)² = 169
// =====================================================
// 13. PRACTICAL EXAMPLES
// =====================================================
console.log('\n--- Practical Examples ---');
// Shopping cart example
const cart = [
{ name: 'Shirt', price: 25, quantity: 2 },
{ name: 'Pants', price: 45, quantity: 1 },
{ name: 'Shoes', price: 80, quantity: 1 },
];
// Total calculation
const total = cart.reduce((sum, item) => {
return sum + item.price * item.quantity;
}, 0);
console.log('Cart total:', total);
// Item summary
const summary = cart.map((item) => ({
name: item.name,
subtotal: item.price * item.quantity,
}));
console.log('Item summary:', summary);
// =====================================================
// 14. PERFORMANCE CONSIDERATIONS
// =====================================================
console.log('\n--- Performance Tips ---');
// Multiple chained operations (multiple passes)
const result1 = [1, 2, 3, 4, 5]
.filter((n) => n > 2)
.map((n) => n * 2)
.filter((n) => n < 10);
// Single reduce (one pass - more efficient for large arrays)
const result2 = [1, 2, 3, 4, 5].reduce((acc, n) => {
if (n > 2) {
const doubled = n * 2;
if (doubled < 10) {
acc.push(doubled);
}
}
return acc;
}, []);
console.log('Chained:', result1);
console.log('Single reduce:', result2);
// =====================================================
// SUMMARY
// =====================================================
console.log('\n--- Summary ---');
console.log(`
HIGHER-ORDER FUNCTIONS:
• Take function as argument, OR
• Return function as result
KEY ARRAY METHODS:
map(fn) → new array (transformed)
filter(fn) → new array (filtered)
reduce(fn, init) → single value
forEach(fn) → undefined (side effects)
find(fn) → first match or undefined
findIndex(fn) → index or -1
some(fn) → boolean (any match?)
every(fn) → boolean (all match?)
sort(fn) → sorted array (in-place)
flatMap(fn) → flattened mapped array
PATTERNS:
• Function factories
• Callbacks
• Method chaining
• Pipe/Compose
`);