如何使用 Ramda 从数组中获取偶数和奇数条目

How to get the even and odd entries from an array with Ramda

我有以下内容:

    var isEven = function (n) { return n % 2 === 0; }
    var isOdd = function (n) { return n % 2 !== 0; }

    var indexedList = function(fn, list) {
        var array = [];
        for (var i = 0; i < list.length; i++) {
            if (fn(i)) {
                array.push(list[i]);
            }
        }

        return array;
    }

是否有与 IndexedList 等效的 Ramda,因此我可以拥有一个仅包含基于偶数索引的元素的数组和一个包含基于奇数索引元素的数组。

默认情况下,Ramda 基于列表的函数不处理索引。这部分是因为它们中的许多更通用,并且还可以与索引没有意义的其他数据结构一起使用。但是有一个标准的机制来改变函数,这样它们就可以传递列表的索引:addIndex.

所以我对此的第一个想法是,首先,把你的 isEven 扩展到

var indexEven = (val, idx) => isEven(idx);

然后您可以像这样将 addIndexfilter and reject 一起使用:

R.addIndex(R.filter)(indexEven, ['a', 'b', 'c', 'd', 'e']); 
//=> ['a', 'c', 'e']
R.addIndex(R.reject)(indexEven, ['a', 'b', 'c', 'd', 'e']); 
//=> ['b', 'd']

或者,如果您同时需要它们,您可以像这样与 partition 一起使用:

R.addIndex(R.partition)(indexEven, ['a', 'b', 'c', 'd', 'e']);
//=> [["a", "c", "e"], ["b", "d"]]

如果愿意,您可以在 Ramda REPL.

上看到实际效果

如果列表长度是偶数,我会选择

R.pluck(0, R.splitEvery(2, ['a','b','c']))

这样做的缺点是,当列表长度为奇数且我们希望 select 偏移量为 1 ( R.pluck(1) ) 时,它会将未定义作为最后一个元素。优点是您可以轻松地 select 每 n 次使用任何偏移量,而 offset < n.

如果您不能接受这个 undefined,那么我发现另一种解决方案比公认的答案更令人满意,因为它不需要定义自定义函数。它不会像公认的答案那样很好地划分它。

偶数:

R.chain(R.head, R.splitEvery(2, ['a','b','c','d']))

奇数:

R.chain(R.last, R.splitEvery(2, ['a','b','c','d']))

从 Ramda 0.25.0 开始,公认的解决方案将不再适用。使用这个:

const splitEvenOdd = R.compose(R.values, R.addIndex(R.groupBy)((val,idx) => idx % 2))

splitEvenOdd(['a','b','c','d','e'])
// => [ [ 'a', 'c', 'e' ], [ 'b', 'd' ] ]