Ruby has a handy function for enumerables called each_cons
. Which "Iterates the given block for each array of consecutive elements." This is really nice. Except that this is definitely an each
method, which returns nil upon completion and not an array of the values you've looped over like map
would.
However, if I have a situation where I need to iterate over an enumerable type, take an element and its cons, then perform some operation on them and return them back into an array what can I do? Normally, I'd use map for this sort of behavior. But map_cons
doesn't exist.
An example:
Given a list of integers, I need to see which ones of those integers repeat and return a list of just those integers
[1, 1, 4, 5, 6, 2, 2] ## I need some function that will get me [1, 2]
I can say:
[1, 1, 4, 5, 6, 2, 2].each_cons(2) {|e| e[0] if e[0] == e[1]}
But, since it each
s over the array, it will complete successfully and return nil
at the end. I need it to behave like map
and not like each
.
Is this behavior something that ruby supports? Am I coming at it from the wrong direction entirely?
The documentation of each_cons ends with this innocent phrase: "If no block is given, returns an enumerator." Most methods of Enumerable do this. What can you do with an Enumerator? Nothing truly impressive . But Enumerators include Enumerable, which does provide a large amount of powerful methods, map
being one of them. So, as Stefan Pochmann does:
[1, 1, 4, 5, 6, 2, 2].each_cons(2).map { |e| e[0] if e[0] == e[1] }
each_cons
is called without a block, so it returns an Enumerator. map
is simply one of its methods.
Just add map
?
[1, 1, 4, 5, 6, 2, 2].each_cons(2).map { |e| e[0] if e[0] == e[1] }
=> [1, nil, nil, nil, nil, 2]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With