44 lines
1.4 KiB
JavaScript
44 lines
1.4 KiB
JavaScript
/**
|
|
* @module find-replace
|
|
*/
|
|
|
|
/**
|
|
* @param {array} - The input array
|
|
* @param {function} - A predicate function which, if returns `true` causes the current item to be operated on.
|
|
* @param [replaceWith] {...any} - If not specified, each found value will be removed. If specified, each found value will be replaced with this value. If the `replaceWith` value is a function, it will be invoked with the found value and its result used as the replace value. If the `replaceWith` function returns an array, the found value will be replaced with each item in the array (not replaced with the array itself).
|
|
* @returns {array}
|
|
* @alias module:find-replace
|
|
*/
|
|
function findReplace (array, findFn, ...replaceWiths) {
|
|
const found = []
|
|
if (!Array.isArray(array)) {
|
|
throw new Error('Input must be an array')
|
|
}
|
|
|
|
for (const [index, value] of array.entries()) {
|
|
let expanded = []
|
|
replaceWiths.forEach(replaceWith => {
|
|
if (typeof replaceWith === 'function') {
|
|
expanded = expanded.concat(replaceWith(value))
|
|
} else {
|
|
expanded.push(replaceWith)
|
|
}
|
|
})
|
|
|
|
if (findFn(value)) {
|
|
found.push({
|
|
index,
|
|
replaceWithValue: expanded
|
|
})
|
|
}
|
|
}
|
|
|
|
for (const item of found.reverse()) {
|
|
const spliceArgs = [item.index, 1].concat(item.replaceWithValue)
|
|
array.splice.apply(array, spliceArgs)
|
|
}
|
|
|
|
return array
|
|
}
|
|
|
|
export default findReplace
|