Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Enumerators

 Enumerators

Oliver Legg

October 14, 2013
Tweet

More Decks by Oliver Legg

Other Decks in Programming

Transcript

  1. Enumerable
    #all? #any? #chunk #collect #collect_concat #count #cycle #detect #drop
    #drop_while #each_cons #each_entry #each_slice #each_with_index
    #each_with_object #entries #find #find_all #find_index #first #flat_map
    #grep #group_by
    #include? #inject #lazy
    #map #max #max_by #min_by #minmax
    #minmax_by #none? #one? #partition #reduce #reject #reverse_each #select
    #slice_before #sort #sort_by #take #take_while #to_a #zip

    View full-size slide

  2. Enumerator
    #each #feed #next #next_values #peek #peek_values #rewind #size
    #with_index #with_object

    View full-size slide

  3. enumerator = [1, 2, 3].each
    # => #
    enumerator = [1, 2, 3].to_enum
    # => #
    enumerator = [1, 2, 3].enum_for(:each)
    # => #

    View full-size slide

  4. def counter
    yield 1
    yield 2
    yield 3
    end
    enumerator = enum_for(:counter)
    enumerator.to_a
    # => [1, 2, 3]

    View full-size slide

  5. with_object
    with_index

    View full-size slide

  6. letters = ['a', 'a', 'a', 'b', 'b', 'c']
    counts = letters.inject({}) do |memo, letter|
    memo[letter] ||= 0
    memo[letter] += 1
    memo
    end
    # => {"a"=>3, "b"=>2, "c"=>1}

    View full-size slide

  7. letters = ['a', 'a', 'a', 'b', 'b', 'c']
    counts = letters.each.with_object({}) do |letter, memo|
    memo[letter] ||= 0
    memo[letter] += 1
    end
    # => {"a"=>3, "b"=>2, "c"=>1}

    View full-size slide

  8. range = (1..10)
    range.map.with_index {|n, i| n * i }
    # => [0, 2, 6, 12, 20, 30, 42, 56, 72, 90]
    range.select.with_index {|_, i| i.even? }
    # => [1, 3, 5, 7, 9]

    View full-size slide

  9. enumerator = [1, 2, 3].each
    # => #
    enumerator.next
    # => 1
    enumerator.next
    # => 2
    enumerator.next
    # => 3
    enumerator.next
    # StopIteration: iteration reached an end

    View full-size slide

  10. enumerator = [1, 2, 3].to_enum
    # => #
    enumerator.peek
    # => 1
    enumerator.peek
    # => 2
    enumerator.peek
    # => 3
    enumerator.next
    # => 1

    View full-size slide

  11. loop do
    i = enumerator.next
    puts i
    # `loop` silently rescues StopIteration
    end

    View full-size slide

  12. fibonacci = Enumerator.new(Float::INFINITY) do |yielder|
    a, b = 0, 1
    loop do
    yielder.yield a
    a, b = b, (a + b)
    end
    end

    View full-size slide

  13. class SumOfNaturalNumbers < Enumerator
    def initialize
    super(Float::INFINITY) do |yielder|
    n = 1
    loop do
    yielder.yield (n * (n + 1)) / 2
    n += 1
    end
    end
    end
    end

    View full-size slide

  14. def fibonacci
    a, b = 0, 1
    loop do
    yield a
    a, b = b, (a + b)
    end
    end
    enumerator = enum_for(:fibonacci)
    # => #

    View full-size slide

  15. require 'prime'
    primes = Prime.instance
    primes
    .select {|i| i.to_s.end_with?('3') }
    .take(10)
    # infinite loop

    View full-size slide

  16. require 'prime'
    primes = Prime.instance
    primes
    .lazy
    .select {|i| i.to_s.end_with?('3') }
    .take(10)
    .to_a
    # => [3, 13, 23, 43, 53, 73, 83, 103, 113, 163]

    View full-size slide

  17. File.open('/usr/share/dict/words')
    .each_line
    .lazy
    .map(&:chomp)
    .take_while {|line| line.length < 10 }
    .to_a

    View full-size slide

  18. mine = ->(repository) { repository.owner == 'olly' }
    cutoff = (Time.now - (365 * 24 * 60 * 60)).to_datetime
    year_old = ->(repository) { repository.commits.first.date > cutoff }
    client.repositories
    .lazy
    .select(&mine)
    .select(&year_old)
    .take(10)
    .each {|repository| puts repository.name }

    View full-size slide