63 lines
1.6 KiB
JavaScript
63 lines
1.6 KiB
JavaScript
|
import arrayify from './node_modules/array-back/index.mjs'
|
||
|
|
||
|
/**
|
||
|
* Find and either replace or remove items in an array.
|
||
|
*
|
||
|
* @module find-replace
|
||
|
* @example
|
||
|
* > const findReplace = require('find-replace')
|
||
|
* > const numbers = [ 1, 2, 3]
|
||
|
*
|
||
|
* > findReplace(numbers, n => n === 2, 'two')
|
||
|
* [ 1, 'two', 3 ]
|
||
|
*
|
||
|
* > findReplace(numbers, n => n === 2, [ 'two', 'zwei' ])
|
||
|
* [ 1, [ 'two', 'zwei' ], 3 ]
|
||
|
*
|
||
|
* > findReplace(numbers, n => n === 2, 'two', 'zwei')
|
||
|
* [ 1, 'two', 'zwei', 3 ]
|
||
|
*
|
||
|
* > findReplace(numbers, n => n === 2) // no replacement, so remove
|
||
|
* [ 1, 3 ]
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @param {array} - The input array
|
||
|
* @param {testFn} - A predicate function which, if returning `true` causes the current item to be operated on.
|
||
|
* @param [replaceWith] {...any} - If specified, found values will be replaced with these values, else removed.
|
||
|
* @returns {array}
|
||
|
* @alias module:find-replace
|
||
|
*/
|
||
|
function findReplace (array, testFn) {
|
||
|
const found = []
|
||
|
const replaceWiths = arrayify(arguments)
|
||
|
replaceWiths.splice(0, 2)
|
||
|
|
||
|
arrayify(array).forEach((value, index) => {
|
||
|
let expanded = []
|
||
|
replaceWiths.forEach(replaceWith => {
|
||
|
if (typeof replaceWith === 'function') {
|
||
|
expanded = expanded.concat(replaceWith(value))
|
||
|
} else {
|
||
|
expanded.push(replaceWith)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
if (testFn(value)) {
|
||
|
found.push({
|
||
|
index: index,
|
||
|
replaceWithValue: expanded
|
||
|
})
|
||
|
}
|
||
|
})
|
||
|
|
||
|
found.reverse().forEach(item => {
|
||
|
const spliceArgs = [ item.index, 1 ].concat(item.replaceWithValue)
|
||
|
array.splice.apply(array, spliceArgs)
|
||
|
})
|
||
|
|
||
|
return array
|
||
|
}
|
||
|
|
||
|
export default findReplace
|