Enumerable和Comparable是Ruby提供的很是重要的模塊。這一篇文章主要介紹Enumerable的一些方法。
Enumerable模塊提供了遍歷,搜索,排序等方法。若是咱們自定義的類須要實現這些方法,必須實現一個each方法。若是須要使用max,min,sort等方法,由於這些方法是集合的元素之間的排序,因此該類還必須使用<=>方法。ui
1.all?[{|obj| block}] -> true of false
code
%w[ant bear cat].all? { |word| word.length >= 3 } #=> true %w[ant bear cat].all? { |word| word.length >= 4 } #=> false [nil, true, 99].all? #=> false
2.any?[{|obj| block}] -> true of false
對象
%w[ant bear cat].any? { |word| word.length >= 3 } #=> true %w[ant bear cat].any? { |word| word.length >= 4 } #=> true [nil, true, 99].any? #=> true
3.chunk{|elt| ...} -> an_enumerator
OR chunk(initial_state){|elt,state|...} -> an_enumerator
從文檔能夠看出:該方法將結果返回一個Enumerator實例。這種狀況在Enumerable模塊中常常能夠看到,那麼咱們就能夠完整的使用Enumerator類的方法,因爲Enumerator類又繼承了Enumerable類的全部方法,因此能夠看到對於返回的結果進行了擴充。
下面列出Enumerator的實例方法,在下一篇文章在詳細的介紹Enumerator。#each,#each_with_index,#each_with_object,#feed,#inspect,#next,#next_values,#peek,#peek_values,#rewind,#size,#with_index,#with_object
栗子:排序
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5].chunk { |n| n.even? }.each { |even, ary| p [even, ary] } #=> [false, [3, 1]] # [true, [4]] # [false, [1, 5, 9]] # [true, [2, 6]] # [false, [5, 3, 5]]
能夠看出來chunk方法返回的Enumerator對象的元素是由(block處理的結果,[元素])組成的繼承
require 'pp' [1,2,3,4,5,6,7,8].chunk do |n| n+1 end.each do |n,arr| pp [n,arr] end
返回的結果以下:ip
[2, [1]] [3, [2]] [4, [3]] [5, [4]] [6, [5]] [7, [6]] [8, [7]] [9, [8]]
此方法很是適合將元素排序,下面的栗子計算了單詞的每一個開頭字母文檔
open('words') do |f| #首先咱們在block中返回words文件中的全部行,沒有對其進行任何處理 #輸出的結果:是每行的開頭字母,以及每行的長度。 f.chunk { |line| line }.each { |ch,line| pp [ch.chr, line[0].length] } end
4.collect{|obj|block}
OR collect -> an_enumerator
get
(1..4).collect { |i| i*i } #=> [1, 4, 9, 16] (1..4).collect { "cat" } #=> ["cat", "cat", "cat", "cat"]
5.collect_concat{|obj| block} -> array
OR collect_concat -> an_enumerator
hash
[1, 2, 3, 4].flat_map { |e| [e, -e] } #=> [1, -1, 2, -2, 3, -3, 4, -4] [[1, 2], [3, 4]].flat_map { |e| e + [100] } #=> [1, 2, 100, 3, 4, 100]
別名就是flat_map
it
6.count -> int
OR count(item) -> int
OR count{ |obj| block } -> int
返回集合的數量,若是傳遞了參數,返回集合中和參數相同元素的個數,若是傳遞了block,返回block中爲真的元素個數
ary = [1, 2, 4, 2] ary.count #=> 4 ary.count(2) #=> 2 ary.count{ |x| x%2==0 } #=> 3
7.cycle(n=nil) {|obj| block} -> nil
OR cycle(n=nil) -> an_enumerator
a = ["a", "b", "c"] a.cycle { |x| puts x } # 打印: a, b, c, a, b, c,...無限多個 a.cycle(2) { |x| puts x } # 打印:a, b, c, a, b, c.
8.detect(ifnone=nil){|obj| block} -> obj or nil
OR detect(ifnone=nil) -> an_enumerator
(1..10).detect { |i| i % 5 == 0 and i % 7 == 0 } #=> nil (1..100).detect { |i| i % 5 == 0 and i % 7 == 0 } #=> 35
固然若是該方法沒有返回值時,能夠爲該方法指定一個默認值:
class Test def default 'I am default' end end t = Test.new pp (1..10).detect(t.method(:default)) { |i| i > 10 }
或者
pp (1..10).detect(lambda { "I am default" }) { |i| i > 10 }
9.drop(n) -> array
刪除前n項元素,返回剩餘元素
a = [1, 2, 3, 4, 5, 0] a.drop(3) #=> [4, 5, 0]
10.drop_while{|arr| block} -> array
OR drop_while -> an_enumerator
a = [1, 2, 3, 4, 5, 0] a.drop_while { |i| i < 3 } #=> [3, 4, 5, 0]
11.each_cons(n){...} -> nil
OR each_cons(n) -> an_enumerator
(1..10).each_cons(3) { |a| p a } # 結果以下 [1, 2, 3] [2, 3, 4] [3, 4, 5] [4, 5, 6] [5, 6, 7] [6, 7, 8] [7, 8, 9] [8, 9, 10]
12.ench_entry{|obj| block} -> enum
%w(1 2 3 4).each_entry {|x| p x}
13.each_slice(n){...} -> nil
OR each_slice(n) -> an_enumerator
(1..10).each_slice(3) { |a| p a } # 結果以下 [1, 2, 3] [4, 5, 6] [7, 8, 9] [10]
14.each_with_index(*args){|obj,i| block} -> enum
OR each_with_index(*args) -> an_enumerator
hash = Hash.new %w(cat dog wombat).each_with_index { |item, index| hash[item] = index } hash #=> {"cat"=>0, "dog"=>1, "wombat"=>2}
15.each_with_object(obj){|(*args), memo_obj|...} -> obj
OR each_with_object(obj) -> an_enumerator
evens = (1..10).each_with_object([]) { |i, a| a << i*2 } #=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
16.entries -> array
(1..7).to_a #=> [1, 2, 3, 4, 5, 6, 7] { 'a'=>1, 'b'=>2, 'c'=>3 }.to_a #=> [["a", 1], ["b", 2], ["c", 3]]
17.find
同detect
18.find_all{|obj| block} -> array
OR find_all -> an_enumerator
(1..10).find_all { |i| i % 3 == 0 } #=> [3, 6, 9] [1,2,3,4,5].select { |num| num.even? } #=> [2, 4]
19.finde_index(value) -> int or nil
OR finde_index{|obj| block} -> int or nil
(1..10).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> nil (1..100).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> 34 (1..100).find_index(50) #=> 49
20.first -> obj or nil
OR first(n) -> an_array
%w[foo bar baz].first #=> "foo" %w[foo bar baz].first(2) #=> ["foo", "bar"] %w[foo bar baz].first(10) #=> ["foo", "bar", "baz"] [].first #=> nil
21.grep(pattern) -> array
OR grep(pattern) {|obj| block} -> array
(1..100).grep 38..44 #=> [38, 39, 40, 41, 42, 43, 44] c = IO.constants c.grep(/SEEK/) #=> [:SEEK_SET, :SEEK_CUR, :SEEK_END] res = c.grep(/SEEK/) { |v| IO.const_get(v) } res #=> [0, 1, 2]
22.group_by{|obj| block} -> a_hash
OR group_by -> an_enumerator
(1..6).group_by { |i| i%3 } #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
23.include?(obj) -> true or false
IO.constants.include? :SEEK_SET #=> true IO.constants.include? :SEEK_NO_FURTHER #=> false
24.inject
# Sum some numbers (5..10).reduce(:+) #=> 45 # Same using a block and inject (5..10).inject { |sum, n| sum + n } #=> 45 # Multiply some numbers (5..10).reduce(1, :*) #=> 151200 # Same using a block (5..10).inject(1) { |product, n| product * n } #=> 151200 # find the longest word longest = %w{ cat sheep bear }.inject do |memo, word| memo.length > word.length ? memo : word end longest #=> "sheep"
25.none? [{|obj| block}] -> true or false
%w{ant bear cat}.none? { |word| word.length == 5 } #=> true %w{ant bear cat}.none? { |word| word.length >= 4 } #=> false [].none? #=> true [nil].none? #=> true [nil, false].none? #=> true
26.one? [{|obj| block} -> true or false]
%w{ant bear cat}.one? { |word| word.length == 4 } #=> true %w{ant bear cat}.one? { |word| word.length > 4 } #=> false %w{ant bear cat}.one? { |word| word.length < 4 } #=> false [ nil, true, 99 ].one? #=> false [ nil, true, false ].one? #=> true
27.partition {|obj| block} -> [true_array, false_array]
分區方法
(1..6).partition { |v| v.even? } #=> [[2, 4, 6], [1, 3, 5]]