Skip to content

Instantly share code, notes, and snippets.

@franciscotln
Last active June 10, 2018 22:24
Show Gist options
  • Save franciscotln/a92bf6d8cf738ad8305049b346a77e02 to your computer and use it in GitHub Desktop.
Save franciscotln/a92bf6d8cf738ad8305049b346a77e02 to your computer and use it in GitHub Desktop.
Function mapFirstN: maps the first N elements found, given a predicate and transformation function
console.clear();
function measure(msg, fn) {
const start = Date.now();
fn();
console.log(msg, Date.now() - start, 'ms');
}
/**
* @description Will look for the first N elements that matches the predicate.
* If found, the elements will be mapped using the provided transformation function
* and the iteration through the collection will be aborted. If not found, a shallow
* copy of the array will be returned with no item changed.
* @name mapFirstN
* @param {Number} n Maximum number of items to be mapped, if found
* @param {Function} predicate Function used to find an item
* @param {Function} transform Function used to transform the found item
* @param {any[]} arr Collection to map over
* @return {any[]} Mapped collection
*/
function mapFirstN(toTake, predicate, transform, arr) {
var result, m, i, item, found;
result = [];
m = arr.length;
found = 0;
i = 0;
for (i; i < m; i++) {
item = arr[i];
if (predicate(item, i) && found < toTake) {
found++;
result.push(transform(item, i));
} else if (found >= toTake) {
return result.concat(arr.slice(i));
} else {
result.push(item);
}
}
return result;
}
/**
* @description Will look for the first element that matches the predicate.
* If found, the element will be mapped using the provided transformation function
* and the iteration through the collection will be aborted. If not found, a shallow
* copy of the array will be returned with no item changed.
* @name mapFirst
* @param {Function} predicate Function used to find an item
* @param {Function} transform Function used to transform the found item
* @param {any[]} arr Collection to map over
* @return {any[]} Mapped collection
*/
function mapFirst(predicate, transform, arr) {
var result, m, i, item;
result = [];
m = arr.length;
i = 0;
for (i; i < m; i++) {
item = arr[i];
if (predicate(item, i)) {
return result.concat(transform(item, i), arr.slice(1 + i));
} else {
result.push(item);
}
}
return result;
}
// node 10.0.0, macbook pro 2,7 GHz Intel Core i5, list length: 200000
const bigList = Array.from({ length: 200000 }, (_, idx) => ({ id: idx + 1, value: idx }));
measure('mapFirst, no element found: ', function () {
// time: ~11 ms
mapFirst(el => el.id === 0, el => ({ ...el, value: el.value + 10 }), bigList);
});
measure('Native, no element found: ', function () {
// time: ~38 ms
bigList.map(el => el.id === 0 ? { ...el, value: el.value + 10 } : el);
});
measure('mapFirst, id: 2: ', function () {
// time: ~7 ms
mapFirst(el => el.id === 2, el => ({ ...el, value: el.value + 10 }), bigList);
});
measure('Native, id: 2: ', function () {
// time: ~38 ms
bigList.map(el => el.id === 2 ? { ...el, value: el.value + 10 } : el);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment