ENumerators
View Slide
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
Enumerator#each #feed #next #next_values #peek #peek_values #rewind #size#with_index #with_object
enumerator = [1, 2, 3].each# => #enumerator = [1, 2, 3].to_enum# => #enumerator = [1, 2, 3].enum_for(:each)# => #
def counteryield 1yield 2yield 3endenumerator = enum_for(:counter)enumerator.to_a# => [1, 2, 3]
with_objectwith_index
letters = ['a', 'a', 'a', 'b', 'b', 'c']counts = letters.inject({}) do |memo, letter|memo[letter] ||= 0memo[letter] += 1memoend# => {"a"=>3, "b"=>2, "c"=>1}
letters = ['a', 'a', 'a', 'b', 'b', 'c']counts = letters.each.with_object({}) do |letter, memo|memo[letter] ||= 0memo[letter] += 1end# => {"a"=>3, "b"=>2, "c"=>1}
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]
Iterator
enumerator = [1, 2, 3].each# => #enumerator.next# => 1enumerator.next# => 2enumerator.next# => 3enumerator.next# StopIteration: iteration reached an end
enumerator = [1, 2, 3].to_enum# => #enumerator.peek# => 1enumerator.peek# => 2enumerator.peek# => 3enumerator.next# => 1
loop doi = enumerator.nextputs i# `loop` silently rescues StopIterationend
Generator
fibonacci = Enumerator.new(Float::INFINITY) do |yielder|a, b = 0, 1loop doyielder.yield aa, b = b, (a + b)endend
class SumOfNaturalNumbers < Enumeratordef initializesuper(Float::INFINITY) do |yielder|n = 1loop doyielder.yield (n * (n + 1)) / 2n += 1endendendend
def fibonaccia, b = 0, 1loop doyield aa, b = b, (a + b)endendenumerator = enum_for(:fibonacci)# => #
LAZY
require 'prime'primes = Prime.instanceprimes.select {|i| i.to_s.end_with?('3') }.take(10)# infinite loop
require 'prime'primes = Prime.instanceprimes.lazy.select {|i| i.to_s.end_with?('3') }.take(10).to_a# => [3, 13, 23, 43, 53, 73, 83, 103, 113, 163]
File.open('/usr/share/dict/words').each_line.lazy.map(&:chomp).take_while {|line| line.length < 10 }.to_a
mine = ->(repository) { repository.owner == 'olly' }cutoff = (Time.now - (365 * 24 * 60 * 60)).to_datetimeyear_old = ->(repository) { repository.commits.first.date > cutoff }client.repositories.lazy.select(&mine).select(&year_old).take(10).each {|repository| puts repository.name }