Ruby/Collections/Enumerable

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск

Содержание

Add cartesian to Enumerable

module Enumerable
  def cartesian(other)
    inject([]) { |res, x| other.inject(res) { |res, y| res << [x,y] } }
  end
end



Building a Histogram

module Enumerable
  def to_histogram
    inject(Hash.new(0)) { |h, x| h[x] += 1; h}
  end
end
p [1, 2, 2, 2, 3, 3].to_histogram
# => {1=>1, 2=>3, 3=>2}
p ["a", "b", nil, "c", "b", nil, "a"].to_histogram
# => {"a"=>2, "b"=>2, "c"=>1, nil=>2}



Call each a number of times

module Enumerable
  def each_n_times(n)
    each { |e| n.times { yield e } }
  end
end
%w{Hello Echo}.each_n_times(3) { |x| puts x }
# Hello
# Hello
# Hello
# Echo
# Echo
# Echo



Enumerable.instance_methods.sort

p Enumerable.instance_methods.sort
# => ["all?", "any?", "collect", "detect", "each_with_index", "entries",
# =>  "find", "find_all", "grep", "include?", "inject", "map", "max",
# =>  "member?", "min", "partition", "reject", "select", "sort", "sort_by",
# =>  "to_a", "zip"]



get Enumerable involved

class AllVowels
  include Enumerable
  @@vowels = %w{a e i o u}
  def each
    @@vowels.each { |v| yield v }
  end
end
x = AllVowels.new
x.collect { |i| i + "x" }
x.detect { |i| i > "j" }
x.select { |i| i > "j" }
x.sort
x.max
x.min



Implementing Enumerable - Write One Method, Get 22 Free

class MultiArray
  include Enumerable
  def initialize(*arrays)
    @arrays = arrays
  end
  def each
    @arrays.each { |a| a.each { |x| yield x } }
  end
end
ma = MultiArray.new([1, 2], [3], [4])
p ma.collect                                   # => [1, 2, 3, 4]
p ma.detect { |x| x > 3 }                      # => 4
p ma.map { |x| x ** 2 }                        # => [1, 4, 9, 16]
p ma.each_with_index { |x, i| puts "Element #{i} is #{x}" }
# Element 0 is 1
# Element 1 is 2
# Element 2 is 3
# Element 3 is 4



randomly each

module Enumerable
  def each_randomly
    (sort_by { rand }).each { |e| yield e }
  end
end
%w{A b c }.each_randomly { |x| puts x }



Sorting an Array by Frequency of Appearance

module Enumerable
  def sort_by_frequency
    histogram = inject(Hash.new(0)) { |hash, x| hash[x] += 1; hash}
    sort_by { |x| [histogram[x], x] }
  end
end
p [1,2,3,4,1,2,4,8,1,4,9,16].sort_by_frequency



Sort on two arrays

class MultiArray
  include Enumerable
  def initialize(*arrays)
    @arrays = arrays
  end
  def each
    @arrays.each { |a| a.each { |x| yield x } }
  end
end
ma = MultiArray.new([1, 2], [3], [4])
ma.sort                                   # => [1, 2, 3, 4]
mixed_type_ma = MultiArray.new([1, 2, 3], ["a", "b", "c"])
mixed_type_ma.sort
# ArgumentError: comparison of Fixnum with String failed



Writing Block Methods that Classify or Collect

module Enumerable
  def find_no_more_than(limit)
    inject([]) do |a,e|
      a << e if yield e
      return a if a.size >= limit
      a
    end
  end
end
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a.find_no_more_than(3) { |x| x % 2 == 0 }            # => [2, 4, 6]