Chaining Ruby enumerators

I want to connect two Ruby enumerators. Give me all the values from the first, then the second, and so on. Ideally, without forcing any lazy evaluations and flat so I don’t have to think about nested stuff. Like so:

xs = [1, 2, 3].to_enum
ys = [4, 5, 6].to_enum
[xs, ys].chain.to_a # => [1, 2, 3, 4, 5, 6]

I couldn’t figure out how to do that with Ruby’s standard library alone. But, it wasn’t that hard to write my own:

def chain(*enums)
  return to_enum(:chain, *enums) unless block_given?

  enums.each { |enum| enum.each { |e| yield e } }
 end

But it seems like Ruby’s library, Enumerable in particular, is so strong I must have missed something. So, mob programmers, is there a better way to do this? A fancier enumerator-combining thing I’m missing?

3 thoughts on “Chaining Ruby enumerators

  1. Daniel Sandbecker

    I’m not sure if you would like to avoid using lazy or avoid evaluating anything lazy. If the latter then this might work:

    ns = [xs, ys].lazy.flat_map(&:lazy)
    => #
    ns.force
    => [1, 2, 3, 4, 5, 6]

  2. Daniel Sandbecker

    Well, that first row would have returned an Enumerator::Lazy if it hadn’t been eaten by the comment system.

Comments are closed.