如何一起提升和组合功能?
How to lift and compose functions together?
我有这个结构中的人员列表:
const people = [
{name: 'jenny', friends: ['jeff']},
{name: 'frank', friends: ['jeff', 'ross']},
{name: 'sarah', friends: []},
{name: 'jeff', friends: ['jenny', 'frank']},
{name: 'russ', friends: []},
{name: 'calvin', friends: []},
{name: 'ross', friends: ['frank']},
];
我想通过两种方式过滤掉人:有朋友和没有朋友;而且我想要 Predicate of the Array.filter
to be lifted,像这样:
const peopleWithoutFriends = people.filter(withoutFriends);
console.log(peopleWithoutFriends);
const peopleWithFriends = people.filter(withFriends);
console.log(peopleWithFriends);
我可以通过显式编写 by
函数来实现此行为,如下所示:
const by = x => i => {
return Boolean(get(i, x));
};
const withFriends = by('friends.length');
const peopleWithFriends = people.filter(withFriends);
console.log(peopleWithFriends);
问题: 如果我想要逆函数,我需要明确地为 peopleWithoutFriends
编写一个全新的函数
const notBy = x => i => {
return !Boolean(get(i, x));
};
const withOutFriends = notBy('friends.length');
const peopleWithoutFriends = people.filter(withOutFriends);
我不想将 by
函数写两次。我宁愿将较小的函数组合在一起。
问题:
如何编写和使用小函数,例如:flow
Boolean
get
curry
not
并为我的 Array.filter 列表编写 withFriends
和 withOutFriends
谓词people
.
回复:https://repl.it/@matthewharwood/ChiefWelloffPaintprogram
const {flow, get, curry} = require('lodash');
const people = [
{name: 'jenny', friends: ['jeff']},
{name: 'frank', friends: ['jeff', 'ross']},
{name: 'sarah', friends: []},
{name: 'jeff', friends: ['jenny', 'frank']},
{name: 'russ', friends: []},
{name: 'calvin', friends: []},
{name: 'ross', friends: ['frank']},
];
const not = i => !i;
const withFriends = i => flow(
Boolean,
get(i, 'friends.length'), // arity of this is 2 so might be harder to lift, is it possible tho with curry?
); // No idea what i'm doing here.
const peopleWithFriends = people.filter(withFriends);
console.log(peopleWithFriends);
const withoutFriends = flow(not, withFriends);
const peopleWithoutFriends = people.filter(withoutFriends);
console.log(peopleWithoutFriends);
由于 with/without 朋友函数的结果是一个布尔值,您可以取反(或补码)其中一个的结果以获得另一个。此外,函数的元数为 1(它们所操作的对象)。
Lodash/fp:
const { flow, get, isEmpty, negate } = _;
const people = [
{name: 'jenny', friends: ['jeff']},
{name: 'frank', friends: ['jeff', 'ross']},
{name: 'sarah', friends: []},
{name: 'jeff', friends: ['jenny', 'frank']},
{name: 'russ', friends: []},
{name: 'calvin', friends: []},
{name: 'ross', friends: ['frank']},
];
const withoutFriends = flow(get('friends'), isEmpty); // create a function that gets the friends array, and check if it is empty
const withFriends = negate(withoutFriends); // negate the result of withoutFriends
const peopleWithFriends = people.filter(withFriends);
console.log(peopleWithFriends);
const peopleWithoutFriends = people.filter(withoutFriends);
console.log(peopleWithoutFriends);
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
拉姆达:
const { pipe, prop, isEmpty, complement } = R;
const people = [
{name: 'jenny', friends: ['jeff']},
{name: 'frank', friends: ['jeff', 'ross']},
{name: 'sarah', friends: []},
{name: 'jeff', friends: ['jenny', 'frank']},
{name: 'russ', friends: []},
{name: 'calvin', friends: []},
{name: 'ross', friends: ['frank']},
];
const withoutFriends = pipe(prop('friends'), isEmpty); // create a function that gets the friends array, and check if it is empty
const withFriends = complement(withoutFriends); // negate the result of withoutFriends
const peopleWithFriends = people.filter(withFriends);
console.log(peopleWithFriends);
const peopleWithoutFriends = people.filter(withoutFriends);
console.log(peopleWithoutFriends);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
备注:
_.flow()
和R.pipe
都从左到右(从上到下)执行序列。函数 _.compose()
和 R.compose
顺序颠倒。
- flow/pipe/compose 中的第一个函数获取传递给组合函数的所有内容。序列中的其他函数总是得到一个参数(前一个函数的结果)/.
- Ramda和Lodash都有一个reject方法,与filter相反,如果predicatereturns
true
,item被移除。例如,R.reject(foo, xs)
等同于 R.filter(R.complement(foo), xs)
。 (@ScottSauyet 在此 comment 中指出)
我有这个结构中的人员列表:
const people = [
{name: 'jenny', friends: ['jeff']},
{name: 'frank', friends: ['jeff', 'ross']},
{name: 'sarah', friends: []},
{name: 'jeff', friends: ['jenny', 'frank']},
{name: 'russ', friends: []},
{name: 'calvin', friends: []},
{name: 'ross', friends: ['frank']},
];
我想通过两种方式过滤掉人:有朋友和没有朋友;而且我想要 Predicate of the Array.filter
to be lifted,像这样:
const peopleWithoutFriends = people.filter(withoutFriends);
console.log(peopleWithoutFriends);
const peopleWithFriends = people.filter(withFriends);
console.log(peopleWithFriends);
我可以通过显式编写 by
函数来实现此行为,如下所示:
const by = x => i => {
return Boolean(get(i, x));
};
const withFriends = by('friends.length');
const peopleWithFriends = people.filter(withFriends);
console.log(peopleWithFriends);
问题: 如果我想要逆函数,我需要明确地为 peopleWithoutFriends
const notBy = x => i => {
return !Boolean(get(i, x));
};
const withOutFriends = notBy('friends.length');
const peopleWithoutFriends = people.filter(withOutFriends);
我不想将 by
函数写两次。我宁愿将较小的函数组合在一起。
问题:
如何编写和使用小函数,例如:flow
Boolean
get
curry
not
并为我的 Array.filter 列表编写 withFriends
和 withOutFriends
谓词people
.
回复:https://repl.it/@matthewharwood/ChiefWelloffPaintprogram
const {flow, get, curry} = require('lodash');
const people = [
{name: 'jenny', friends: ['jeff']},
{name: 'frank', friends: ['jeff', 'ross']},
{name: 'sarah', friends: []},
{name: 'jeff', friends: ['jenny', 'frank']},
{name: 'russ', friends: []},
{name: 'calvin', friends: []},
{name: 'ross', friends: ['frank']},
];
const not = i => !i;
const withFriends = i => flow(
Boolean,
get(i, 'friends.length'), // arity of this is 2 so might be harder to lift, is it possible tho with curry?
); // No idea what i'm doing here.
const peopleWithFriends = people.filter(withFriends);
console.log(peopleWithFriends);
const withoutFriends = flow(not, withFriends);
const peopleWithoutFriends = people.filter(withoutFriends);
console.log(peopleWithoutFriends);
由于 with/without 朋友函数的结果是一个布尔值,您可以取反(或补码)其中一个的结果以获得另一个。此外,函数的元数为 1(它们所操作的对象)。
Lodash/fp:
const { flow, get, isEmpty, negate } = _;
const people = [
{name: 'jenny', friends: ['jeff']},
{name: 'frank', friends: ['jeff', 'ross']},
{name: 'sarah', friends: []},
{name: 'jeff', friends: ['jenny', 'frank']},
{name: 'russ', friends: []},
{name: 'calvin', friends: []},
{name: 'ross', friends: ['frank']},
];
const withoutFriends = flow(get('friends'), isEmpty); // create a function that gets the friends array, and check if it is empty
const withFriends = negate(withoutFriends); // negate the result of withoutFriends
const peopleWithFriends = people.filter(withFriends);
console.log(peopleWithFriends);
const peopleWithoutFriends = people.filter(withoutFriends);
console.log(peopleWithoutFriends);
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
拉姆达:
const { pipe, prop, isEmpty, complement } = R;
const people = [
{name: 'jenny', friends: ['jeff']},
{name: 'frank', friends: ['jeff', 'ross']},
{name: 'sarah', friends: []},
{name: 'jeff', friends: ['jenny', 'frank']},
{name: 'russ', friends: []},
{name: 'calvin', friends: []},
{name: 'ross', friends: ['frank']},
];
const withoutFriends = pipe(prop('friends'), isEmpty); // create a function that gets the friends array, and check if it is empty
const withFriends = complement(withoutFriends); // negate the result of withoutFriends
const peopleWithFriends = people.filter(withFriends);
console.log(peopleWithFriends);
const peopleWithoutFriends = people.filter(withoutFriends);
console.log(peopleWithoutFriends);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
备注:
_.flow()
和R.pipe
都从左到右(从上到下)执行序列。函数_.compose()
和R.compose
顺序颠倒。- flow/pipe/compose 中的第一个函数获取传递给组合函数的所有内容。序列中的其他函数总是得到一个参数(前一个函数的结果)/.
- Ramda和Lodash都有一个reject方法,与filter相反,如果predicatereturns
true
,item被移除。例如,R.reject(foo, xs)
等同于R.filter(R.complement(foo), xs)
。 (@ScottSauyet 在此 comment 中指出)