-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
44 lines (38 loc) · 1.38 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
* @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