原始地址:https://github.com/30-seconds...
filterNonUnique
过滤调数组中的非唯一值。
使用 Array.prototype.filter()
过滤掉在原数组中存在相同元素的元素。
// 左右开弓,同一元素因为索引相同最后返回 true 会被过滤掉
const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
// example
filterNonUnique([1, 2, 2, 3, 4, 4, 5]); // [1, 3, 5]
filterNonUniqueBy
使用给定比较器函数过滤掉数组中符合要求的非唯一值。
使用 Array.prototype.every()
校验数组内的元素是否是符合给定函数的唯一值,再使用 Array.prototype.filter()
过滤掉非唯一值的元素,剩下的是唯一存在的符合给定函数的元素。
const filterNonUniqueBy = (arr, fn) =>
arr.filter((v, i) => arr.every((x, j) => (i === j) === fn(v, x, i, j)));
// own understand
const filterNonUniqueBy = (arr, fn) => {
return arr.filter((v, i) => {
// 返回最后 arr.every = false 的元素
// 即整个数组中都没有匹配到的
return arr.every((x, j) => {
// 同索引下为 true ,即当前元素
const indexBool = i === j;
// 当前元素匹配成功最后返回 true (true === true)
// 不同元素最后匹配成功返回 false (false === true)
// 不同元素最后匹配失败返回 true (false === false)
return indexBool === fn(v, x, i, j);
});
});
};
// example
filterNonUniqueBy(
[
{ id: 0, value: 'a' },
{ id: 1, value: 'b' },
{ id: 2, value: 'c' },
{ id: 1, value: 'd' },
{ id: 0, value: 'e' }
],
(a, b) => a.id == b.id
); // [ { id: 2, value: 'c' } ]
findLast
从数组的右侧开始循环,找出数组中符合给定函数的第一个元素的值。
使用 Array.prototype.filter()
移除数组中不符合指定函数的元素,返回结果集的最后一个元素。
const findLast = (arr, fn) => arr.filter(fn).pop();
// example
findLast([1, 2, 3, 4], n => n % 2 === 1); // 3
findLastIndex
从数组的右侧开始循环,找出数组中符合给定函数的第一个元素的索引。
使用 Array.prototype.map()
对数组进行处理获取数组的值和索引,对新的到的值和索引使用 Array.prototype.filter()
对数据使用给定函数得到符合要求的数组,最后获取最后一个符合要求的元素的索引。
const findLastIndex = (arr, fn) =>
arr
.map((val, i) => [i, val])
.filter(([i, val]) => fn(val, i, arr))
.pop()[0];
// own understand
const findLastIndex = (arr, fn) => {
const arrNew = arr.map((val, i) => [i, val]);
const arrFilter = arrNew.filter(([i, val]) => fn(val, i, arr));
return arrFilter.pop()[0];
};
// example
findLastIndex([1, 2, 3, 4], n => n % 2 === 1); // 2 (index of the value 3)
flatten
将数组递归成指定深度的数组。
指定了一个默认为 1
的指定深度,使用 Array.prototype.reduce()
对数组进行循环,对数组元素进行校验,对递归深度大于 1
和当前元素为数组的情况,对当前元素进行递归,其他情况下可以直接放入到结果集中。
const flatten = (arr, depth = 1) =>
arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v), []);
// own understand
const flatten = (arr, depth = 1) => {
return arr.reduce((acc, val) => {
if (depth > 1 && Array.isArray(val)) {
return acc.concat(flatten(val, depth - 1));
}
return acc.concat(val);
}, []);
};
// example
flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]
forEachRight
从数组的右侧开始循环,对每一个元素执行一次给定的函数。
使用 Array.prototype.slice(0)
对数组进行一次浅拷贝,再使用 Array.prototype.reverse()
将浅拷贝的数组的顺序倒置,最后使用 Array.prototype.forEach()
对数组进行循环调用给定函数。
const forEachRight = (arr, callback) =>
arr
.slice(0)
.reverse()
.forEach(callback);
// own understand
const forEachRight = (arr, callback) => {
const arrNew = arr.slice(0);
const arrReverse = arrNew.reverse();
return arrReverse.forEach(callback);
};
// example
forEachRight([1, 2, 3, 4], val => console.log(val)); // '4', '3', '2', '1'
groupBy
基于给定的函数或属性将数组进行分组,分组后的 key
为经过给定函数或属性处理过的结果。
使用 Array.prototype.map()
对数组的元素进行处理得到新的数组,使用 Array.prototype.reduce()
对新数组进行分组提取,但是要将原数组的内容放到结果集内。
const groupBy = (arr, fn) =>
arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val, i) => {
acc[val] = (acc[val] || []).concat(arr[i]);
return acc;
}, {});
// own understand
const groupBy = (arr, fn) => {
const arrNew = arr.map(typeof fn === 'function' ? fn : val => val[fn]);
return arrNew.reduce((acc, val, i) => {
acc[val] = (acc[val] || []).concat(arr[i]);
return acc;
}, {});
};
// example
groupBy([6.1, 4.2, 6.3], Math.floor); // {4: [4.2], 6: [6.1, 6.3]}
groupBy(['one', 'two', 'three'], 'length'); // {3: ['one', 'two'], 5: ['three']}
head
返回数组的第一个元素。
const head = arr => arr[0];
// example
head([1, 2, 3]); // 1
indexOfAll
返回数组内给定元素的所有索引,不存在时返回一个空数组。
使用 Array.prototype.reduce()
对数据进行循环,如果当前元素和给定的元素全等,则在结果的数组上加上当前索引。
const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);
// own understand
const indexOfAll = (arr, val) => {
return arr.reduce((acc, el, i) => {
if (el === val) {
return [...acc, i];
}
return acc;
}, []);
}
// example
indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
indexOfAll([1, 2, 3], 4); // []
initial
返回数组除最后一个元素之外的其他数组,即删除最后一个元素。
使用 Array.prototype.slice(0, -1)
截取数组,相当于删除了最后一个元素。
const initial = arr => arr.slice(0, -1);
// example
initial([1, 2, 3]); // [1,2]