var take = R.curry(function take(count, o) {
return R.pick(R.take(count, R.keys(o)), o);
});
此函数从对象中获取count
个键,按其出现的顺序排列。我用它来限制分组的数据集。
我知道存在占位符参数,例如R.__
,但我不能围绕这个特殊情况。
答案 0 :(得分:1)
这可以归功于R.converge
,但我不建议在这种情况下进行无点接种。
// take :: Number -> Object -> Object
var take = R.curryN(2,
R.converge(R.pick,
R.converge(R.take,
R.nthArg(0),
R.pipe(R.nthArg(1),
R.keys)),
R.nthArg(1)));
需要注意的一点是,由于R.keys
返回的列表顺序未定义,因此未定义此函数的行为。
答案 1 :(得分:1)
我同意@davidchambers认为最好不要这么做。这个解决方案比那个解决方案更清洁,但仍然不像我原来的那样好:
// take :: Number -> Object -> Object
var take = R.converge(
R.pick,
R.useWith(R.take, R.identity, R.keys),
R.nthArg(1)
);
useWith
和converge
的相似之处在于它们接受了许多函数参数,并将除第一个之外的所有函数调用的结果传递给第一个函数参数。区别在于converge
将它收到的所有参数传递给每个参数,useWith
将它们分开,将一个传递给每个函数。这是我第一次看到它用于组合它们,但它似乎在这里有意义。
该属性排序问题应该在ES6中解决(final draft现在已经解决了!)但它是still controversial。
你提到需要花一些时间来解决这个问题。这应该有助于至少显示它与原始函数的等价关系,如果不是如何推导它:
var take = R.converge(
R.pick,
R.useWith(R.take, R.identity, R.keys),
R.nthArg(1)
);
// definition of `converge`
(count, obj) => R.pick(R.useWith(R.take, R.identity, R.keys)(count, obj),
R.nthArg(1)(count, obj));
// definition of `nthArg`
(count, obj) => R.pick(R.useWith(R.take, R.identity, R.keys)(count, obj), obj);
// definition of `useWith`
(count, obj) => R.pick(R.take(R.identity(count), R.keys(obj)), obj);
// definition of `identity`
(count, obj) => R.pick(R.take(count, R.keys(obj)), obj);
自version 18起,converge
和useWith
都已更改为二进制。每个都采用目标函数和辅助函数列表。这会稍微改变上述内容:
// take :: Number -> Object -> Object
var take = R.converge(R.pick, [
R.useWith(R.take, [R.identity, R.keys]),
R.nthArg(1)
]);