原始地址: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])
),
[]);
};
// example
permutations([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));
};
// example
let 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 understand
const 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;
};
// example
let 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 understand
const 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;
};
// example
let 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));
};
// example
var 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 understand
const 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;
};
// example
const 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]);
// example
reduceSuccessive([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));
// example
reduceWhich([1, 3, 2]); // 1
reduceWhich([1, 3, 2], (a, b) => b - a); // 3
reduceWhich([{ 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));
// example
reject(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 understand
const 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);
}, []);
};
// example
remove([1, 2, 3, 4], n => n % 2 === 0); // [2, 4]