原文链接:yazeedb.com/posts/10-js…
原作者:Yazeed Bzadough
翻译者:发呆小贤
在上一篇文章中,我向你提出了使用reduce去创建一些众所周知的函数。本文将向你展示如何实现其中的一些,另外还有一些其它的函数。
总的来说,我们将研究10个实用的函数。它们在您的项目上非常方便,而且最重要的是,它们是用reduce来实现的!我从RamdaJS库中获得了很多灵感,看看吧!
1. some
参数
predicate- 返回true或false的函数array- 要测试的列表
描述
如果任一项的 predicate 返回 true, some 返回 true,否则返回 false。
实现
const some = (predicate, array) => array.reduce((acc, value) => acc || predicate(value), false);
用例
const equals3 = (x) => x === 3;
some(equals3, [3]); // true
some(equals3, [3, 3, 3]); // true
some(equals3, [1, 2, 3]); // true
some(equals3, [2]); // false
2. all
参数
predicate- 返回true或false的函数array- 要测试的列表
描述
如果每一项的 predicate 都返回 true, all 返回 true,否则返回 false。
实现
const all = (predicate, array) => array.reduce((acc, value) => acc && predicate(value), true);
用例
const equals3 = (x) => x === 3;
all(equals3, [3]); // true
all(equals3, [3, 3, 3]); // true
all(equals3, [1, 2, 3]); // false
all(equals3, [3, 2, 3]); // false
3. none
参数
predicate- 返回true或false的函数array- 要测试的列表
描述
如果每一项的 predicate 都返回 false, none 返回 true,否则返回 false。
实现
const none = (predicate, array) => array.reduce((acc, value) => acc && !predicate(value), true);
用例
const isEven = (x) => x % 2 === 0;
none(isEven, [1, 3, 5]); // true
none(isEven, [1, 3, 4]); // false
none(equals3, [1, 2, 4]); // true
none(equals3, [1, 2, 3]); // false
4. map
参数
transformFunction- 在每个元素上运行的函数array- 要转换的列表
描述
返回一个新数组,每一项都经过了 transformFunction 的转换
实现
const map = (transformFunction, array) =>
array.reduce((newArray, item) => {
newArray.push(transformFunction(item));
return newArray;
}, []);
用例
const double = (x) => x * 2;
const reverseString = (string) =>
string
.split('')
.reverse()
.join('');
map(double, [100, 200, 300]);
// [200, 400, 600]
map(reverseString, ['Hello World', 'I love map']);
// ['dlroW olleH', 'pam evol I']
5. filter
参数
predicate- 返回true或false的函数array- 要过滤的列表
描述
返回一个新数组。如果 predicate 返回 true,则将该元素添加至新数组中,否则该元素将被排除在新数组之外。
实现
const filter = (predicate, array) =>
array.reduce((newArray, item) => {
if (predicate(item) === true) {
newArray.push(item);
}
return newArray;
}, []);
用例
const isEven = (x) => x % 2 === 0;
filter(isEven, [1, 2, 3]);
// [2]
filter(equals3, [1, 2, 3, 4, 3]);
// [3, 3]
6. reject
参数
predicate- 返回true或false的函数array- 要过滤的列表
描述
就像 filter,但行为相反。
如果 predicate 返回 false,则将该元素添加至新数组中,否则该元素将被排除在新数组之外。
实现
const reject = (predicate, array) =>
array.reduce((newArray, item) => {
if (predicate(item) === false) {
newArray.push(item);
}
return newArray;
}, []);
用例
const isEven = (x) => x % 2 === 0;
reject(isEven, [1, 2, 3]);
// [1, 3]
reject(equals3, [1, 2, 3, 4, 3]);
// [1, 2, 4]
7. find
参数
predicate- 返回true或false的函数array- 要查找的列表
描述
返回第一个与 predicate 匹配到的元素,如果没有匹配的则返回 undefined
实现
const find = (predicate, array) =>
array.reduce((result, item) => {
if (result !== undefined) {
return result;
}
if (predicate(item) === true) {
return item;
}
return undefined;
}, undefined);
用例
const isEven = (x) => x % 2 === 0;
find(isEven, []); // undefined
find(isEven, [1, 2, 3]); // 2
find(isEven, [1, 3, 5]); // undefined
find(equals3, [1, 2, 3, 4, 3]); // 3
find(equals3, [1, 2, 4]); // undefined
8. partition
参数
predicate- 返回true或false的函数array- 列表
描述
基于 predicate 把一个数组“划分”或者分割成两部分,如果 predicate 返回 `true``,该元素进入列表1,否则进入列表2
实现
const partition = (predicate, array) =>
array.reduce(
(result, item) => {
const [list1, list2] = result;
if (predicate(item) === true) {
list1.push(item);
} else {
list2.push(item);
}
return result;
},
[[], []]
);
用例
const isEven = (x) => x % 2 === 0;
partition(isEven, [1, 2, 3]);
// [[2], [1, 3]]
partition(isEven, [1, 3, 5]);
// [[], [1, 3, 5]]
partition(equals3, [1, 2, 3, 4, 3]);
// [[3, 3], [1, 2, 4]]
partition(equals3, [1, 2, 4]);
// [[], [1, 2, 4]]
// [1, 2, 4]
9. pluck
参数
key- 从对象中选取的键名array- 列表
描述
从数组中的每个项目中抽取给定 key 的值。返回这些值组成新数组。
实现
const pluck = (key, array) =>
array.reduce((values, current) => {
values.push(current[key]);
return values;
}, []);
用例
pluck('name', [{ name: 'Batman' }, { name: 'Robin' }, { name: 'Joker' }]);
// ['Batman', 'Robin', 'Joker']
pluck(0, [[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
// [1, 4, 7]
10. scan
参数
reducer- 标准的rducer函数,它接收两个参数 - 数组的累加器和当前值。initialValue- 累加器的初始值array- 列表
描述
它的工作原理和 reduce 相似,不同的是 reduce 只返回最后结果,而 scan 返回由每次累加器结果组成的数组。
实现
const scan = (reducer, initialValue, array) => {
const reducedValues = [];
array.reduce((acc, current) => {
const newAcc = reducer(acc, current);
reducedValues.push(newAcc);
return newAcc;
}, initialValue);
return reducedValues;
};
用例
const add = (x, y) => x + y;
const multiply = (x, y) => x * y;
scan(add, 0, [1, 2, 3, 4, 5, 6]);
// [1, 3, 6, 10, 15, 21] - Every number added from 1-6
scan(multiply, 1, [1, 2, 3, 4, 5, 6]);
// [1, 2, 6, 24, 120, 720] - Every number multiplied from 1-6