简体   繁体   中英

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

I have the following:

    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;
    }

Is there a Ramda equivalent of IndexedList so I can have an array of just the even index based elements and an array of odd based index elements.

Ramda's list-based functions by default do not deal with indices. This, in part, is because many of them are more generic and also work with other data structures where indices don't make sense. But there is a standard mechanism for altering functions so that they do pass the indices of your lists along: addIndex .

So my first thought on this is to first of all, take your isEven and extend it to

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

Then you can use addIndex with filter and reject like this:

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']

Or if you want them both at once, you can use it with partition like this:

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

You can see this in action, if you like, on the Ramda REPL .

If the list length is even, I would go with

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

The disadvantage of this is that it will give undefined as a last element, when list length is odd and we want to select with offset 1 ( R.pluck(1) ). The advantage is that you can easily select every nth with any offset while offset < n.

If you can't live with this undefined than there is another solution that I find more satisfying than accepted answer, as it doesn't require defining a custom function. It won't partition it nicely though, as the accepted answer does.

For even:

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

For odd:

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

As of Ramda 0.25.0, the accepted solution will not work. Use this:

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' ] ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM