Last active
June 10, 2018 22:24
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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