如何用R.compose重写这个

时间:2015-04-14 00:18:59

标签: ramda.js

var take = R.curry(function take(count, o) {
    return R.pick(R.take(count, R.keys(o)), o);
});

此函数从对象中获取count个键,按其出现的顺序排列。我用它来限制分组的数据集。

我知道存在占位符参数,例如R.__,但我不能围绕这个特殊情况。

2 个答案:

答案 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)
);

useWithconverge的相似之处在于它们接受了许多函数参数,并将除第一个之外的所有函数调用的结果传递给第一个函数参数。区别在于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);

更新2

version 18起,convergeuseWith都已更改为二进制。每个都采用目标函数和辅助函数列表。这会稍微改变上述内容:

// take :: Number -> Object -> Object
var take = R.converge(R.pick, [
    R.useWith(R.take, [R.identity, R.keys]), 
    R.nthArg(1)
]);