原始地址:https://github.com/30-seconds...
permutations
生成数组元素的所有排列组成的数组(包含重复项)。
对于数组长度为 2
的数组直接返回结果,对于长度小于 2
的数组直接返回原数组。对于其他长度的数组,首先使用 Array.prototype.reduce()
对数组中的元素进行循环,在每一个循环中,使用 Array.prototype.slice()
剔除本次循环的值,,并对剩余的元素数组递归使用当前方法,最后使用 Array.prototype.map()
将结果数组拼接起来。
const permutations = arr => { if (arr.length <= 2) return arr.length === 2 ? [arr, [arr[1], arr[0]]] : arr; return arr.reduce( (acc, item, i) => acc.concat( permutations([...arr.slice(0, i), ...arr.slice(i + 1)]).map(val => [item, ...val]) ), [] );};// examplepermutations([1, 33, 5]); // [ [ 1, 33, 5 ], [ 1, 5, 33 ], [ 33, 1, 5 ], [ 33, 5, 1 ], [ 5, 1, 33 ], [ 5, 33, 1 ] ]
pull
将给定数组中的指定值移除。
通过 Array.isArray()
校验给定参数是否是数组,非数组的时候将后续所有参数转成参数数组。使用 Array.prototype.filter()
和 Array.prototype.includes()
获取出留存的元素数组,然后使用 Array.prototype.length = 0
将原数组设置为空数组,再将留存的元素使用 Array.prototype.push()
填充到原数组中。
const pull = (arr, ...args) => { let argState = Array.isArray(args[0]) ? args[0] : args; let pulled = arr.filter((v, i) => !argState.includes(v)); arr.length = 0; pulled.forEach(v => arr.push(v));};// examplelet myArray = ['a', 'b', 'c', 'a', 'b', 'c'];pull(myArray, 'a', 'c'); // myArray = [ 'b', 'b' ]
pullAtIndex
更改给定的数组过滤掉指定索引的值,返回被移除的值的数组,改变原来的数组。
使用 Array.prototype.includes()
获取出被移除的元素组成的数组,然后再使用 Array.prototype.filter()
过滤掉被移除的元素,将原数组的长度设置为 0
后成为一个空数组,再将留存的元素使用 Array.prototype.push()
填充到原数组内,最后返回被移除的元素数组。
const pullAtIndex = (arr, pullArr) => { let removed = []; let pulled = arr .map((v, i) => (pullArr.includes(i) ? removed.push(v) : v)) .filter((v, i) => !pullArr.includes(i)); arr.length = 0; pulled.forEach(v => arr.push(v)); return removed;};// own understandconst pullAtIndex = (arr, pullArr) => { const removed = []; const left = []; for (let i = 0; i < arr.length; i++) { if (pullArr.includes(i)) { removed.push(arr[i]); } else { left.push(arr[i]); } } arr.length = 0; left.forEach(item => arr.push(item)); return removed;};// examplelet myArray = ['a', 'b', 'c', 'd'];let pulled = pullAtIndex(myArray, [1, 3]); // myArray = [ 'a', 'c' ] , pulled = [ 'b', 'd' ]
pullAtValue
更改给定的数组过滤掉指定的值,返回被移除的值的数组,改变原来的数组。
使用 Array.prototype.filter()
和 Array.prototype.includes()
获取最后存留的元素,使用 Array.prototype.length = 0
可以直接将数组设置为空数组,然后循环存留的元素数组并将其中的值使用 Array.prototype.push()
填充到原数组中,返回最后被删除的元素。
const pullAtValue = (arr, pullArr) => { let removed = [], pushToRemove = arr.forEach((v, i) => (pullArr.includes(v) ? removed.push(v) : v)), mutateTo = arr.filter((v, i) => !pullArr.includes(v)); arr.length = 0; mutateTo.forEach(v => arr.push(v)); return removed;};// own understandconst pullAtValue = (arr, pullArr) => { const removed = []; for (let i = 0; i < arr.length; i++) { if (pullArr.includes(arr[i])) { removed.push(arr[i]); arr.splice(i--, 1); } } return removed;};// examplelet myArray = ['a', 'b', 'c', 'd'];let pulled = pullAtValue(myArray, ['b', 'd']); // myArray = [ 'a', 'c' ] , pulled = [ 'b', 'd' ]
pullBy
根据给定的迭代器函数,将数组中符合要求的元素过滤掉,改变原来的数组。
首先需要检查给定的最后一个参数是否是一个函数。使用 Array.prototype.map()
对给定的参数数组应用迭代器函数,然后使用 Array.prototype.filter()
和 Array.prototype.includes()
过滤掉不符合要求的数组,然后将给定的参数数组的长度设置为 0
,最后使用 Array.prototype.push()
将结果放到参数数组内。
const pullBy = (arr, ...args) => { const length = args.length; let fn = length > 1 ? args[length - 1] : undefined; fn = typeof fn == 'function' ? (args.pop(), fn) : undefined; let argState = (Array.isArray(args[0]) ? args[0] : args).map(val => fn(val)); let pulled = arr.filter((v, i) => !argState.includes(fn(v))); arr.length = 0; pulled.forEach(v => arr.push(v));};// examplevar myArray = [{ x: 1 }, { x: 2 }, { x: 3 }, { x: 1 }];pullBy(myArray, [{ x: 1 }, { x: 3 }], o => o.x); // myArray = [{ x: 2 }]
reducedFilter
对给定的对象数组应用指定的过滤函数后,返回结果数组中指定的字段。
首先使用 Array.prototype.filter()
对过滤掉给定数组中不符合要求的元素,对剩余的元素数组使用 Array.prototype.map()
进行循环,再循环中使用 Array.prototype.reduce()
对给定的 keys
数组进行循环,从结果数组中取出符合要求的对象作为结果集。
const reducedFilter = (data, keys, fn) => data.filter(fn).map(el => keys.reduce((acc, key) => { acc[key] = el[key]; return acc; }, {}) );// own understandconst reducedFilter = (data, keys, fn) => { const arrFilter = data.filter(fn); const resultList = []; for (const item of arrFilter) { const result = {}; for (const key of keys) { result[key] = item[key]; } resultList.push(result); } return resultList;};// exampleconst data = [ { id: 1, name: 'john', age: 24 }, { id: 2, name: 'mike', age: 50 }];reducedFilter(data, ['id', 'name'], item => item.age > 24); // [{ id: 2, name: 'mike'}]
reduceSuccessive
对一个数组中得值循环应用给定得累加器函数,返回应用后的结果数组。
const reduceSuccessive = (arr, fn, acc) => arr.reduce((res, val, i, arr) => (res.push(fn(res.slice(-1)[0], val, i, arr)), res), [acc]);// examplereduceSuccessive([1, 2, 3, 4, 5, 6], (acc, val) => acc + val, 0); // [0, 1, 3, 6, 10, 15, 21]
reduceWhich
给数组中的元素应用给定比较器函数后,返回数组的最大值/最小值,默认取最小值。
使用 Array.prototype.reduce()
对数组进行循环,比较数组前后两个元素,默认取比较小的值。
const reduceWhich = (arr, comparator = (a, b) => a - b) => arr.reduce((a, b) => (comparator(a, b) >= 0 ? b : a));// examplereduceWhich([1, 3, 2]); // 1reduceWhich([1, 3, 2], (a, b) => b - a); // 3reduceWhich( [{ name: 'Tom', age: 12 }, { name: 'Jack', age: 18 }, { name: 'Lucy', age: 9 }], (a, b) => a.age - b.age); // {name: "Lucy", age: 9}
reject
返回给定数组中无法通过给定校验函数的所有元素组成的数组。
const reject = (pred, array) => array.filter((...args) => !pred(...args));// examplereject(x => x % 2 === 0, [1, 2, 3, 4, 5]); // [1, 3, 5]reject(word => word.length > 4, ['Apple', 'Pear', 'Kiwi', 'Banana']); // ['Pear', 'Kiwi']
remove
移除数组中通过指定校验函数的元素,返回被移除的元素组成的数组,原数组只剩余不能通过指定校验函数的元素。
使用 Array.isArray()
校验给定的参数是否是数组,非数组的时候直接返回空数组,然后使用 Array.prototype.filter()
过滤出只符合要求的元素数组,使用 Array.prototype.reduce()
得到的新数组进行循环,在循环中将符合要求的元素通过 Array.prototype.splice()
从给的数组中移除掉,并将这个元素返回。
const remove = (arr, func) => Array.isArray(arr) ? arr.filter(func).reduce((acc, val) => { arr.splice(arr.indexOf(val), 1); return acc.concat(val); }, []) : [];// own understandconst remove = (arr, func) => { if (!Array.isArray(arr)) { return []; } // 获取需要保留的元素 const newArr = arr.filter(func); return newArr.reduce((acc, val) => { arr.splice(arr.indexOf(val), 1); return acc.concat(val); }, []);};// exampleremove([1, 2, 3, 4], n => n % 2 === 0); // [2, 4]