본문으로 건너뛰기

forEach

Executes a callback function for each element in an array with early termination support. Iterates through each element of the array and executes the provided callback function. If the callback returns false, the iteration stops immediately. This provides more control than the standard forEach by allowing early exit from the loop.

Signature

const forEach: <Type>(array: Type[], callback: (item: Type, index: number, array: Type[]) => boolean | void) => void

Parameters

NameTypeDescription
array-Array to iterate over
callback-Callback function to apply to each element. Stops iteration if returns false

Examples

Basic iteration

import { forEach } from '@winglet/common-utils';

const numbers = [1, 2, 3, 4, 5];
forEach(numbers, (num, index) => {
console.log(`Index ${index}: ${num}`);
// No return value - continues iteration
});
// Output: Index 0: 1, Index 1: 2, Index 2: 3, Index 3: 4, Index 4: 5

Early termination

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

forEach(numbers, (num, index) => {
console.log(`Processing: ${num}`);
if (num === 5) {
console.log('Found 5, stopping iteration');
return false; // Stop iteration
}
// Implicit return undefined - continues iteration
});
// Output: Processing: 1, Processing: 2, Processing: 3, Processing: 4, Processing: 5, Found 5, stopping iteration

Search for first matching element

interface User {
id: number;
name: string;
email: string;
}

const users: User[] = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' },
{ id: 3, name: 'Charlie', email: 'charlie@example.com' }
];

let foundUser: User | undefined;
forEach(users, (user) => {
if (user.name === 'Bob') {
foundUser = user;
return false; // Stop searching
}
});
console.log(foundUser); // { id: 2, name: 'Bob', email: 'bob@example.com' }

Conditional processing with early exit

const tasks = ['task1', 'task2', 'error', 'task4', 'task5'];
const results: string[] = [];

forEach(tasks, (task, index) => {
if (task === 'error') {
console.log(`Error encountered at index ${index}`);
return false; // Stop processing on error
}
results.push(`Processed ${task}`);
});
console.log(results); // ['Processed task1', 'Processed task2']

Working with complex objects

interface Product {
id: number;
name: string;
price: number;
inStock: boolean;
}

const products: Product[] = [
{ id: 1, name: 'Laptop', price: 999, inStock: true },
{ id: 2, name: 'Phone', price: 699, inStock: false },
{ id: 3, name: 'Tablet', price: 399, inStock: true }
];

let totalValue = 0;
forEach(products, (product, index, array) => {
if (!product.inStock) {
console.log(`Skipping out-of-stock item: ${product.name}`);
return; // Continue to next item
}

totalValue += product.price;
console.log(`Added ${product.name} (${product.price}) - Running total: ${totalValue}`);

// Stop if total exceeds budget
if (totalValue > 1000) {
console.log('Budget exceeded, stopping calculation');
return false;
}
});

Using all callback parameters

const items = ['a', 'b', 'c', 'd', 'e'];

forEach(items, (item, index, array) => {
console.log(`Item: ${item}, Index: ${index}, Array length: ${array.length}`);

// Stop at middle element
if (index >= Math.floor(array.length / 2)) {
console.log('Reached middle, stopping');
return false;
}
});
// Output: Item: a, Index: 0, Array length: 5
// Item: b, Index: 1, Array length: 5
// Item: c, Index: 2, Array length: 5
// Reached middle, stopping

Playground

import { forEach } from '@winglet/common-utils';

const numbers = [1, 2, 3, 4, 5];
forEach(numbers, (num, index) => {
console.log(`Index ${index}: ${num}`);
// No return value - continues iteration
});
// Output: Index 0: 1, Index 1: 2, Index 2: 3, Index 3: 4, Index 4: 5

Notes

Early Termination: Iteration stops immediately when the callback returns false. Any other return value (including undefined) continues the iteration.

Callback Parameters: The callback function receives three parameters:

  • item: The current element being processed
  • index: The index of the current element
  • array: The entire source array

Performance: Uses simple for-loop for optimal performance. Early termination can provide significant performance benefits when searching large arrays.

Side Effects: This function is intended for side effects (logging, mutation, etc.) rather than creating new arrays. Use map or filter for functional transformations.