class Enumdate::EnumMerger

Create new Enumerator merging multiple enumerators.

All enumerators should yield objects that respond to `<=>` method. enums = (EnumMerger.new << enum1 << enum2).to_enum

Public Class Methods

new() click to toggle source
# File lib/enumdate/enum_merger.rb, line 12
def initialize
  @enumerators = []
end

Public Instance Methods

<<(enumerator) click to toggle source

Add enumerator

# File lib/enumdate/enum_merger.rb, line 36
def <<(enumerator)
  @enumerators << enumerator.to_enum
  self
end
each() { |current| ... } click to toggle source

Imprement each for Enumrator class

# File lib/enumdate/enum_merger.rb, line 17
def each
  return enum_for(:each) unless block_given?

  previous, has_valid_previous = nil, false
  loop do
    current = next_minimum(@enumerators)
    next if has_valid_previous && current == previous

    yield current
    previous, has_valid_previous = current, true
  end
end
rewind() click to toggle source

Imprement rewind for Enumrator class

# File lib/enumdate/enum_merger.rb, line 31
def rewind
  @enumerators.map(&:rewind)
end

Private Instance Methods

minimum_enumrator(enumerators) click to toggle source
# File lib/enumdate/enum_merger.rb, line 51
def minimum_enumrator(enumerators)
  min_e, min_v = enumerators.first, nil
  enumerators.each do |e|
    v = e.peek
    min_e, min_v = e, v if min_v.nil? || v < min_v
  rescue StopIteration
    # do nothing
  end
  min_e
end
next_minimum(enumerators) click to toggle source

Yield next minimum value

# File lib/enumdate/enum_merger.rb, line 44
def next_minimum(enumerators)
  raise StopIteration if enumerators.empty?

  # Could raise StopIteration
  minimum_enumrator(enumerators).next
end