(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = global || self, global.findReplace = factory()); }(this, function () { 'use strict'; /** * Takes any input and guarantees an array back. * * - converts array-like objects (e.g. `arguments`) to a real array * - converts `undefined` to an empty array * - converts any another other, singular value (including `null`) into an array containing that value * - ignores input which is already an array * * @module array-back * @example * > const arrayify = require('array-back') * * > arrayify(undefined) * [] * * > arrayify(null) * [ null ] * * > arrayify(0) * [ 0 ] * * > arrayify([ 1, 2 ]) * [ 1, 2 ] * * > function f(){ return arrayify(arguments); } * > f(1,2,3) * [ 1, 2, 3 ] */ function isObject (input) { return typeof input === 'object' && input !== null } function isArrayLike (input) { return isObject(input) && typeof input.length === 'number' } /** * @param {*} - the input value to convert to an array * @returns {Array} * @alias module:array-back */ function arrayify (input) { if (Array.isArray(input)) { return input } else { if (input === undefined) { return [] } else if (isArrayLike(input)) { return Array.prototype.slice.call(input) } else { return [ input ] } } } /** * 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 } return findReplace; }));