scootloops is a JavaScript utility library that provides advanced iteration patterns and utilities not directly available in native JavaScript. It offers functions for performance optimization, complex data structure traversal, advanced control flow, parallel processing, and data transformation.
npm install scootloopsimport { upLoop, times, filterIt, parallelIt, chunkIt } from 'scootloops';Loops through a range of numbers in ascending order with optional step and early exit support.
upLoop(start, end, callback, step = 1)Parameters:
start(Number): Starting numberend(Number): Ending number (exclusive)callback(Function): Function called for each iterationstep(Number, optional): Increment step (default: 1)
Return false from callback to break early.
// Basic usage
upLoop(1, 6, (i) => console.log(i)); // 1, 2, 3, 4, 5
// With step
upLoop(0, 10, (i) => console.log(i), 2); // 0, 2, 4, 6, 8
// Early exit
upLoop(1, 100, (i) => {
console.log(i);
if (i === 5) return false; // stops at 5
});Loops through a range of numbers in descending order.
downLoop(start, end, callback, step = 1)// Basic usage
downLoop(5, 0, (i) => console.log(i)); // 5, 4, 3, 2, 1
// With step
downLoop(20, 0, (i) => console.log(i), 3); // 20, 17, 14, 11, 8, 5, 2Executes a callback a specified number of times, passing the index (0-based).
times(count, callback)// Execute 5 times
times(5, (i) => console.log(`Iteration ${i}`));
// Create array
const randoms = [];
times(10, () => randoms.push(Math.random()));
// Early exit
times(100, (i) => {
if (i === 10) return false;
});Filters arrays using string-based operators. Supports property access for objects.
filterIt(array, condition, value)Basic filtering:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
filterIt(numbers, 'even'); // [2, 4, 6, 8, 10]
filterIt(numbers, 'odd'); // [1, 3, 5, 7, 9]
filterIt(numbers, 'greaterThan', 5); // [6, 7, 8, 9, 10]
filterIt(numbers, 'between', [3, 7]); // [3, 4, 5, 6, 7]Object property filtering:
const people = [
{ name: 'John', age: 25 },
{ name: 'Jane', age: 35 },
{ name: 'Bob', age: 40 }
];
filterIt(people, 'age.greaterThan', 30);
// [{ name: 'Jane', age: 35 }, { name: 'Bob', age: 40 }]
filterIt(people, 'name.startsWith', 'J');
// [{ name: 'John', age: 25 }, { name: 'Jane', age: 35 }]Available operators:
Numeric: even, odd, greaterThan, lessThan, between
String: startsWith, endsWith, contains, camelCase, matches (regex)
Type checking: isObject, isClass, isArray, isNumber, isString
Value checking: exactMatch, truthy, falsy, isEmpty, hasLength
Sums all elements in an array with optional initial value.
sumIt(array, initialValue = 0)sumIt([1, 2, 3, 4, 5]); // 15
sumIt([1, 2, 3], 10); // 16Divides an array into chunks of specified size.
const chunks = chunkIt([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3);
// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]Creates sliding windows from an array.
const windows = windowIt([1, 2, 3, 4, 5], 3);
// [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
// With step
const steppedWindows = windowIt([1, 2, 3, 4, 5, 6], 2, 2);
// [[1, 2], [3, 4], [5, 6]]Zips multiple arrays into tuples.
const zipped = zipIt([1, 2, 3], ['a', 'b', 'c'], [true, false, true]);
// [[1, 'a', true], [2, 'b', false], [3, 'c', true]]Processes items in parallel with concurrency control.
const results = await parallelIt(
[1, 2, 3, 4, 5],
async (item) => {
const response = await fetch(`https://api.example.com/${item}`);
return response.json();
},
2 // max 2 concurrent requests
);Executes a function with automatic retry logic and exponential backoff.
const result = await retryIt(
async (attempt) => {
const response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error('Failed');
return response.json();
},
{
retries: 5,
delay: 1000,
exponential: true
}
);Processes items asynchronously with controlled concurrency and optional delays.
const results = await asyncIterateIt(
urls,
async (url) => {
const response = await fetch(url);
return response.json();
},
{
concurrency: 3,
delay: 500
}
);Creates a memoized version of a function.
const fibonacci = (n) => {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
};
const memoizedFib = memoizeIt(fibonacci);
console.log(memoizedFib(40)); // Fast even for large numbersCreates a throttled function (max once per interval).
const throttledScroll = throttleIt(() => {
console.log('Scroll handled');
}, 200);
window.addEventListener('scroll', throttledScroll);Creates a debounced function (delays invocation).
const debouncedSearch = debounceIt((query) => {
console.log(`Searching for: ${query}`);
}, 300);
searchInput.addEventListener('input', (e) => {
debouncedSearch(e.target.value);
});Iterates through nested objects/arrays.
const nestedObj = {
a: 1,
b: { c: 2, d: [3, 4, { e: 5 }] }
};
deepIt(nestedObj, (value, path) => {
console.log(`${path}: ${value}`);
});Traverses a tree structure using depth-first search.
const tree = {
value: 'root',
children: [
{ value: 'A', children: [{ value: 'A1' }, { value: 'A2' }] },
{ value: 'B', children: [{ value: 'B1' }] }
]
};
dfsIt(tree, (node, depth) => {
console.log(`${depth}: ${node.value}`);
});
// Output: 0: root, 1: A, 2: A1, 2: A2, 1: B, 2: B1Traverses a tree structure using breadth-first search.
bfsIt(tree, (node) => {
console.log(node.value);
});
// Output: root, A, B, A1, A2, B1Composes functions left-to-right.
const addTwo = (x) => x + 2;
const multiplyByThree = (x) => x * 3;
const square = (x) => x * x;
const calculate = pipeIt(addTwo, multiplyByThree, square);
console.log(calculate(5)); // ((5 + 2) * 3)² = 441- Removed
mapIt- Use nativearray.map()instead - Removed
forEach- Use nativearray.forEach()orarray.filter().forEach() - Renamed
reduceIttosumIt- Now only sums arrays. For custom reducers, use nativearray.reduce() upLoopanddownLoopnow support step parameter and early exitfilterItproperty access fixed and new operators addedparallelItnow processes items concurrently (not sequentially)
Contributions are welcome! Feel free to open a pull request.
MIT License