30 Seconds of Code is a brilliant collection of JavaScript snippets, digestible in ≤ 30 seconds. Anyone looking to master JavaScript should go through the entire thing.
30秒的代码是精妙JavaScript片段集合,可在≤30秒内消化。 任何想要精通JavaScript的人都应该仔细研究整个过程。
Inspired by Ramda, I contributed when()
to 30secondsofcode’s official GitHub repo. This is one my favorite functions.
受Ramda的启发,我将when()
贡献给30secondsofcode的官方GitHub存储库 。 这是我最喜欢的功能之一。
when()
takes 3 parameters:
when()
采用3个参数:
pred
: A predicate function (must returntrue
orfalse
)pred
:谓词函数(必须返回true
或false
)whenTrue
: A function to run ifpred
returnstrue
.whenTrue
:如果pred
返回true
运行的函数。A value:
x
.值:
x
。
Here’s the most basic implementation:
这是最基本的实现:
when = (pred, whenTrue, x) => {
if (pred(x)) {
return whenTrue(x);
} else {
return x;
}
};
Which you can shorten to:
您可以将其缩短为:
when = (pred, whenTrue, x) => (pred(x) ? whenTrue(x) : x);
Let’s say we want to triple even numbers
假设我们想将偶数增加三倍
when((x) => x % 2 === 0, (x) => x * 3, 2);
// 6
We got 6
because 2
is an even number. What if we pass 11
?
我们得到6
是因为2
是偶数。 如果我们通过11
怎么办?
when((x) => x % 2 === 0, (x) => x * 3, 11);
// 11
更进一步 (A Step Further)
when
currently needs all 3 parameters at once–what if we could supply just the first 2, and give x
later on?
当前when
需要同时使用所有3个参数-如果我们可以仅提供前两个参数,然后再给出x
,该怎么办?
when = (pred, whenTrue) => (x) => (pred(x) ? whenTrue(x) : x);
This version’s what I submitted to 30secondsofcode.org. Now our code’s more flexible.
这个版本是我提交给30secondsofcode.org的版本 。 现在我们的代码更加灵活。
tripleEvenNums = when((x) => x % 2 === 0, (x) => x * 3);
tripleEvenNums(20); // 60
tripleEvenNums(21); // 21
tripleEvenNums(22); // 66
甚至更远 (Even Further Beyond)
We can pass x
later because when(pred, whenTrue)
returns a function expecting x
. What if we curry when()
?
我们可以稍后传递x
因为when(pred, whenTrue)
返回一个期望x
的函数。 如果我们咖喱when()
怎么办?
If you’re new to currying see my article on it.
如果您是新手,请参阅我的文章 。
A curried function doesn’t need all its parameters at once. You can supply some and get a function that takes the rest, allowing for powerful patterns.
咖喱函数不需要一次所有的参数。 您可以提供一些功能,并获得剩下的功能,以实现强大的模式。
一个愚蠢的例子 (A Silly Example)
Imagine we have two lists of people, both contain a guy named Bobo
.
想象一下,我们有两个人名单,每个人都包含一个名叫Bobo
。
Bobo
wants a nickname for each list.
Bobo
希望为每个列表起一个昵称。
If we find
Bobo
in list 1, change his name toB Money
.如果我们在列表1中找到
Bobo
,Bobo
他的名字更改为B Money
。If we find
Bobo
in list 2, change his name toBo-bob
.如果我们在列表2中找到
Bobo
,Bobo
其名称更改为Bo-bob
。
Currying when
allows us to easily write a function for each concern.
Curing when
允许我们轻松地为每个关注点编写一个函数。
If you’re following along, here’s a curry
function from 30secondsofcode.org.
如果您正在遵循,这里是30secondsofcode.org中的curry
函数。
curry = (fn, arity = fn.length, ...args) =>
arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args);
We’ll need a predicate to find Bobo
.
我们需要一个谓词才能找到Bobo
。
isBobo = (person) => person.name === 'Bobo';
To keep our functions pure, we’ll need a way to immutably change a person’s name.
为了保持功能纯净,我们需要一种不变地更改人名的方法。
changeName = (newName, obj) => ({
...obj,
name: newName
});
Let’s also curry it so we can supply just newName
.
我们还要对其进行咖喱处理,以便仅提供newName
。
changeName = curry((newName, obj) => ({
...obj,
name: newName
}));
Here’s our lists.
这是我们的清单。
list1 = [
{
name: 'Bobo',
id: 1,
iq: 9001
},
{
name: 'Jaime',
id: 2,
iq: 9000
},
{
name: 'Derek',
id: 3,
iq: 8999
}
];
list2 = [
{
name: 'Sam',
id: 1,
iq: 600
},
{
name: 'Bobo',
id: 2,
iq: 9001
},
{
name: 'Peter',
id: 3,
iq: 8
}
];
Let’s map over list1
.
让我们映射到list1
。
doIfBobo = when(isBobo);
renameToBMoney = changeName('B Money');
list1.map(doIfBobo(renameToBMoney));
Our result:
我们的结果:
[
{
name: 'B Money',
id: 1,
iq: 9001
},
{
name: 'Jaime',
id: 2,
iq: 9000
},
{
name: 'Derek',
id: 3,
iq: 8999
}
];
Because of when
, we only changed Bobo
and ignored everyone else!
由于when
,我们只换了Bobo
而忽略了其他所有人!
Now map over list2
.
现在映射到list2
。
renameToBoBob = changeName('Bo-bob');
list2.map(doIfBobo(renameToBoBob));
Our result:
[{
"name": "Sam",
"id": 1,
"iq": 600
},
{
"name": "Bo-bob",
"id": 2,
"iq": 9001**
},
{
"name": "Peter",
"id": 3,
"iq": 8
}
];
Looks good to me! We gave Bobo
his nicknames without affecting anyone else.
在我看来很好! 我们给了Bobo
他的昵称,却没有影响到其他人。
If you’re further interested, consider these links:
如果您进一步感兴趣,请考虑以下链接: