方法列表:php
slice!()
,注意原處修改eql?
方法比較對象時採用的是hash值比較initialize_copy()
迭代數組中每一個元素,並對它們每個都執行塊中的邏輯,並返回新數組。java
map()
不會修改原始數組對象,map!()
會修改原始對象。python
map()和collect()等價,同理map!()和collect!()等價。算法
arr = [1, 2, 3, 4, 5] new_arr = arr.map{|a| 2*a} p new_arr1 # [2, 4, 6, 8, 10] p arr # [1, 2, 3, 4, 5] new_arr1 = arr.map!{|a| a**2} p arr # [1, 4, 9, 16, 25] p new_arr1 # [1, 4, 9, 16, 25]
arr.zip(arg, ...) → new_ary arr.zip(arg, ...) {|arr| block} → nil
將0或多個arg數組和arr數組的元素一一對應地合併起來。合併時,數量以arr的元素數量爲準,不足的以nil補足,多餘的元素則忽略。shell
a = [ 4, 5, 6 ] b = [ 7, 8, 9 ] [1, 2, 3].zip(a, b) # [[1,4,7],[2,5,8],[3,6,9]] [1, 2].zip(a, b) # [[1, 4, 7], [2, 5, 8]] a.zip([1, 2], [8]) # [[4,1,8],[5,2,nil],[6,nil,nil]]
若是使用語句塊的方式,那麼每次合併後的子數組將傳遞給語句塊中的變量,而後應用語句塊的邏輯,但注意它返回的結果爲nil。因此,zip()語句塊中的block應當是那些能作實際操做的語句,而不是像一種返回值的方式返回操做後的結果,這樣會丟棄結果。看下面示例:數組
a = [ 4, 5, 6 ] b = [ 7, 8, 9 ] [1, 2].zip(a, b) # [[1, 4, 7], [2, 5, 8]] [1, 2].zip(a, b) do |x| x.reduce(:+) # (1).不合理 end [1, 2].zip(a, b) do |x| p x.reduce(:+) # (2).合理 end sum = 0 [1, 2].zip(a, b) do |x| sum += x.reduce(:+) # (3).合理 end p sum
首先,上面zip()兩次傳遞到語句塊中的變量分別是[1, 4, 7]
和[2, 5, 8]
。x.reduce(:+)
表示將x容器(此處爲數組)中的元素全都相加。因此,第一次迭代語句塊時,x.reduce(:+)
的結果是1+4+7=12,第二次迭代的結果是2+5+8=15。ruby
可是在(1)中,它僅僅只是相加了,加了以後結果就被丟棄了,它不會做爲新數組的元素返回,由於zip()使用語句塊時返回的是nil,而不是新數組。app
因此,在(2)中,對相加以後的結果加了一個p()動做將其輸出,也就是使用了x.reduce的結果,並無丟棄。dom
同理,在(3)中,將相加以後的結果加總到sum上,使得最後sum的值被保留,這裏也使用了x.reduce的結果,並無丟棄。測試
filter()、filter!()分別等價於select()、select!()。
迭代數組,並從數組中選擇那些符合語句塊中測試條件的元素,最後組成一個新數組。
select()
不會修改原始數組對象,select!()
會修改原始對象。
arr = [1, 2, 3, 4, 5, 6] new_arr = arr.select {|a| a > 3} p new_arr # [4, 5, 6] p arr # [1, 2, 3, 4, 5, 6] new_arr = arr.select! {|a| a > 3} p new_arr # [4, 5, 6] p arr # [4, 5, 6]
和select()是相反的行爲,從數組中篩選不知足條件的元素。
reject()
不會修改原始數組對象,reject!()
會修改原始對象。
arr = [1, 2, 3, 4, 5, 6] new_arr = arr.reject {|a| a > 3} p new_arr # [1, 2, 3] p arr # [1, 2, 3, 4, 5, 6] new_arr = arr.reject! {|a| a > 3} p new_arr # [1, 2, 3] p arr # [1, 2, 3]
keep_if {|item| block} → ary keep_if → Enumerator
keep_if()
從數組中刪除不知足語句塊中條件的元素,即保留知足條件的元素。
注意原處修改對象。
arr = [1, 2, 3, 4, 5, 6] new_arr = arr.keep_if {|a| a < 4} p new_arr # [1, 2, 3] p arr # [1, 2, 3]
ary.uniq -> new_ary ary.uniq {|item| ...} -> new_ary ary.uniq! -> ary or nil ary.uniq! {|item| ...} -> ary or nil
對於語句塊格式的語法,將迭代每一個元素,而後根據語句塊中的返回值做爲重複值比較的依據。
對於uniq!(),若是沒有任何重複元素能夠去除,則返回nil,這時原數組不變,這是帶有後綴!
但不改變原對象的一個特例。其它狀況這些方法均返回去重後的數組。
a = [ "a", "a", "b", "b", "c" ] a.uniq # ["a", "b", "c"], a不變 b = [["student","sam"], ["student","george"], ["teacher","matz"]] b.uniq {|s| s.first} # [["student","sam"],["teacher","matz"]],b不變 a = [ "a", "a", "b", "b", "c" ] a.uniq! # ["a", "b", "c"],a已變 b = [ "a", "b", "c" ] b.uniq! # nil,b不變 c = [["student","sam"], ["student","george"], ["teacher","matz"]] c.uniq! {|s| s.first} # [["student","sam"],["teacher","matz"]],c已變
compact! → new_ary compact! → ary or nil
去除數組中全部nil元素。
帶感嘆號的方法表示原處修改,若是沒有nil元素可去除,則返回nil。
["a",nil,"b",nil,"c",nil].compact #["a","b","c"] ["a",nil,"b",nil,"c"].compact! # ["a","b","c"] ["a","b","c"].compact! # nil
all? [{ |obj| block } ] → true or false all?(pattern) → true or false any? [{ |obj| block } ] → true or false any?(pattern) → true or false none? [{ |obj| block } ] → true or false none?(pattern) → true or false one? [{ |obj| block } ] → true or false one?(pattern) → true or false
對於這些方法,均有三種行爲:
===
的測試符號去判斷容器中是否全部元素(all)、是否任一元素(any)、是否沒有元素(none)、是否有且只有一個元素(one)知足條件須要特別對待的是空數組,雖然空數組自身是一個bool true,但空數組沒有元素:
# all() %w[ant bear cat].all? { |word| word.length >= 3 } # true %w[ant bear cat].all? { |word| word.length >= 4 } # false %w[ant bear cat].all?(/t/) # false [1, 2i, 3.14].all?(Numeric) # true [nil, true, 99].all? # false [].all? # true
# any() %w[ant bear cat].any? { |word| word.length >= 3 } # true %w[ant bear cat].any? { |word| word.length >= 4 } # true %w[ant bear cat].any?(/d/) # false [nil, true, 99].any?(Integer) # true [nil, true, 99].any? # true [].any? # false
# none() %w{ant bear cat}.none? {|word| word.length == 5} # true %w{ant bear cat}.none? {|word| word.length >= 4} # false %w{ant bear cat}.none?(/d/) # true [1, 3.14, 42].none?(Float) # false [].none? # true [nil].none? # true [nil, false].none? # true [nil, false, true].none? # false
# one() %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 %w{ant bear cat}.one?(/t/) # false [ nil, true, 99 ].one? # false [ nil, true, false ].one? # true [ nil, true, 99 ].one?(Integer) # true [].one? # false
計算數組中知足條件的元素個數。
count → int count(obj) → int count {|item| block} → int
==
進行等值測試ary = [1, 2, 4, 2] ary.count # 4,數組元素個數 ary.count(2) # 2,等於2的元素個數 ary.count {|x| x%2 == 0} # 3,偶元素個數
二者等價,均返回數組元素個數。和不帶參數的count()等價。
cycle(n=nil) {|obj| block} → nil cycle(n=nil) → Enumerator
迭代數組每一個元素並調用語句塊,而後循環n次整個數組的迭代過程(注意是按整個數組計算次數,而不是對每一個元素,因此是先迭代完一次數組,再循環迭代第二次數組,以此類推)。
若是不給參數或參數爲nil,則無限循環迭代。
a = ["a", "b", "c"] a.cycle {|x| puts x} # a,b,c,a,b,c, ... forever a.cycle(2) {|x| puts x} # a,b,c,a,b,c
ary.delete(obj) -> item or nil ary.delete(obj) {block} -> item or result of block
刪除數組中全部等於obj
的對象,返回最後被刪除的元素。若是沒有元素可刪除,則返回nil。若是使用了語句塊,則在無元素可刪除的狀況下返回語句塊的結果而不是nil。至關於語句塊提供了默認值來替代nil返回值。
注意原處修改。
a = [ "a", "b", "b", "b", "c" ] a.delete("b") # "b" a # ["a", "c"] a.delete("z") # nil a.delete("z") {"not found"} # "not found"
delete_at(index) → obj or nil
刪除數組中指定索引位置處的元素,並返回該元素,若是索引越界則返回nil。
注意原處修改。
a = ["ant", "bat", "cat", "dog"] a.delete_at(2) # "cat" a # ["ant", "bat", "dog"] a.delete_at(99) # nil
delete_if {|item| block} → ary delete_if → Enumerator
delete_if()
從數組中刪除知足語句塊中條件的元素。
注意原處修改。
arr = [1, 2, 3, 4, 5, 6] new_arr = arr.delete_if {|a| a < 4} p new_arr # [4, 5, 6] p arr # [4, 5, 6]
dig(idx, ...) → object
根據給定的索引idx去提取數組中的元素。這主要用於從多層嵌套的數組取元素,特別是層次複雜的數組。
a = [[1, [2, 3]]] a.dig(0, 1, 1) # 3 a.dig(1, 2, 3) # nil a.dig(0, 0, 0) # TypeError: Integer does not have #dig method [42, {foo: :bar}].dig(1, :foo) # :bar
其中:
dig(0,1,1)
表示首先從數組a中取idx=0的元素,即取得[1,[2,3]]
,再取得idx=1的元素,即[2,3]
,最後再取得idx=1的元素,即3。
dig(1,2,3)
在第1次取元素的過程越界,由於[[1, [2, 3]]]
只有一個元素。
dig(0,0,0)
第一次取得[1, [2, 3]]
,第二次取得1,由於1再也不是數組,因此第三次取元素時報錯。
first → obj or nil first(n) → new_ary last → obj or nil last(n) → new_ary
取數組頭部或數組尾部的一個或n個元素,但不修改原數組。
a = %w(a b c d) a.first # "a" a.last # "d" a.first(2) # ["a", "b"] a.last(2) # ["c", "d"] a.first(10) # ["a", "b", "c", "d"] a.last(10) # ["a", "b", "c", "d"] [].first # nil [].first(2) # []
drop(n) → new_ary take(n) → new_ary
take()從數組頭部返回前n個元素。
drop()從數組頭部刪除前n個元素,而後將剩下的元素做爲新數組返回。
原數組不變。
# drop() a = ["a", "b", "c"] a.drop(2) # 返回["c"],a不變 # take() a = [1, 2, 3, 4, 5, 0] a.take(3) # [1, 2, 3]
drop_while {|obj| block} → new_ary drop_while → Enumerator take_while {|obj| block} → new_ary take_while → Enumerator
take_while()從數組頭部開始迭代元素,直到遇到不滿組語句塊中條件的元素中止迭代,而後返回全部已迭代的知足條件的元素。
drop_while()從數組頭部開始迭代元素,一直刪除元素直到遇到不知足語句塊中條件的元素中止迭代。而後將剩下的元素做爲新數組返回。
注意,不是原處修改。
# drop_while() arr = [1, 2, 3, 4, 5, 6] new_arr = arr.drop_while {|a| a<4} p new_arr # [4, 5, 6] p arr # [1, 2, 3, 4, 5, 6] # take_while() a = [1, 2, 3, 4, 5, 0] a.take_while {|i| i < 3} #=> [1, 2]
fetch(index) → obj fetch(index, default) → obj fetch(index) {|index| block} → obj
按照給定index獲取數組中的元素。若是index越界,則根據三種不一樣形式進行處理:
a = [ 11, 22, 33, 44 ] a.fetch(1) #=> 22 a.fetch(-1) #=> 44 a.fetch(4, 'cat') #=> "cat" a.fetch(100) {|i| puts "#{i} is out of bounds"} #=> "100 is out of bounds"
# 原處修改 fill(obj) → ary fill(obj, start [, length]) → ary fill(obj, range) → ary fill {|index| block} → ary fill(start [, length]) {|index| block} → ary fill(range) {|index| block} → ary
前三種形式,據使用obj值替換數組中給定範圍內元素的值:
fill(obj)
:使用obj替換全部元素fill(obj, start [, len])
:替換從start開始,長度len個元素,沒有給len則替換後面全部元素fill(obj, range)
:替換range所指定的範圍元素後三種形式,將傳遞數組索引到語句塊,且給定範圍內的元素將使用語句塊的計算結果進行替換,範圍以外的則保留使用索引值元素。
a = [ "a", "b", "c", "d" ] a.fill("x") # ["x", "x", "x", "x"] a.fill("z", 2) # ["x", "x", "z", "z"] a.fill("y", 0..1) # ["y", "y", "z", "z"] a.fill {|i| i*i} # [0, 1, 4, 9] a.fill(-2) {|i| i*i*i} # [0, 1, 8, 27]
push(obj, ...) → ary append(obj, ...) → ary pop → obj or nil pop(n) → new_ary
注意原處修改。
slice!(-n,n
)# push()、append() a = [ "a", "b", "c" ] a.push("d","e","f") # %w[a b c d e f] [1,2,3].push(4).push(5) # [1,2,3,4,5]
# pop() a = [ "a", "b", "c", "d" ] a.pop # "d" a.pop(2) # ["b", "c"] a # ["a"]
unshift(obj, ...) → ary prepend(obj, ...) → ary shift → obj or nil shift(n) → new_ary
注意原處修改。
slice!(0,n)
# unshift、prepend() a = [ "b", "c", "d" ] a.unshift("a") #=> ["a", "b", "c", "d"] a.unshift(1, 2) #=> [ 1, 2, "a", "b", "c", "d"]
# shift args = ["-m", "-q", "filename"] args.shift # "-m" args # ["-q", "filename"] args = [ "-m", "-q", "filename" ] args.shift(2) #=> ["-m", "-q"] args #=> ["filename"]
flatten → new_ary flatten(level) → new_ary flatten! → ary or nil flatten!(level) → ary or nil
將多層次的嵌套數組壓平,level能夠指定最多壓到那一層。對於帶感嘆號後綴的方法,若是數組沒法再壓或層數不夠,則返回nil。
s = [ 1, 2, 3 ] # [1,2,3] t = [ 4, 5, 6, [7, 8] ] # [4,5,6,[7,8]] a = [ s, t, 9, 10 ] # [[1,2,3],[4,5,6,[7,8]],9,10] a.flatten # [1,2,3,4,5,6,7,8,9,10] a = [ 1, 2, [3, [4, 5] ] ] a.flatten(1) # [1, 2, 3, [4, 5]] a = [ 1, 2, [3, [4, 5] ] ] a.flatten! #=> [1, 2, 3, 4, 5] a.flatten! #=> nil,已經壓平了 a #=> [1, 2, 3, 4, 5] a = [ 1, 2, [3, [4, 5] ] ] a.flatten!(1) #=> [1, 2, 3, [4, 5]] a.flatten!(1) #=> [1, 2, 3, 4, 5] a.flatten!(1) #=> nil
計算數組的hash值。執行eql?()
的比較時,其比較依據就是hash值。
[1, 2].hash # 2027605168499122706 [1, 2.0].hash # 3393919734812826294
include?(object) → true or false
判斷數組中是否包含某元素。判斷的依據是使用==
比較。
a = [ "a", "b", "c" ] a.include?("b") # true a.include?("z") # false [1, 2.0].include?(2) # true
index(obj) → int or nil index {|item| block} → int or nil index → Enumerator rindex(obj) → int or nil rindex {|item| block} → int or nil rindex → Enumerator
搜索數組中知足條件的元素並返回其索引位置,搜索不到將返回nil。
# index(obj)、rindex(obj) # 返回數組中第一個、最後一個等於obj的元素位置 # 使用"=="進行測試 a = [ "a", "b", "c" ] p a.index("b") # 1 p a.index("z") # nil p a.index {|x| x == "b"} # 1 # (r)index {|item| block} # 返回第一個/最後一個知足語句塊中條件的元素位置 a = [ "a", "b", "b", "b", "c" ] p a.rindex("b") # 3 p a.rindex("z") # nil p a.rindex {|x| x == "b"} # 3
二者等價。
initialize_copy(other_ary) → ary
使用other_ary數組替換當前數組中的元素,並按需收縮、擴展。
注意原處修改。
a = %w(a b c d e) # ["a", "b", "c", "d", "e"] a.replace(%w[x y z]) # ["x", "y", "z"] a # ["x", "y", "z"]
join(separator=$,) → str
將數組各元素經過鏈接符鏈接起來,轉換成字符串返回。
不給sep時默認以$,
做爲鏈接符,若是$,
爲nil(默認就是nil),則默認使用空字符進行鏈接。
嵌套數組會遞歸鏈接。
鏈接符必須是字符串類型。
實際上,join()的過程是:將數組各元素全都使用to_s
轉換成字符串,而後對鏈接符使用to_str
轉換成字符串。
["a","b","c"].join # "abc" ["a","b","c"].join("-") # "a-b-c" ["a",[1,2,[:x,:y]], "b" ].join("-") # "a-1-2-x-y-b" # 數值不能做爲鏈接符,由於它沒有定義to_str %w(perl shell ruby).join(1) # TypeError
max → obj max {|a, b| block} → obj max(n) → array max(n) {|a, b| block} → array min → obj min {|a, b| block} → obj min(n) → array min(n) {|a, b| block} → array
無參數、無語句塊的形式,表示從數組中返回最大/最小的元素。何爲最大/最小,只有數組中全部元素都實現了Comparable
模塊才容許比較,也就是能使用<=>
對數組不一樣元素之間進行比較。
帶語句塊形式的形式,表示將每一個元素傳遞到語句塊以後通過一番處理,而後經過<=>
比較獲得返回結果。
帶參數的形式則表示以數組的方式返回最大/最小的n個元素,也就是返回前幾名對象。
ary = %w(albatross dog horse) ary.max # "horse" ary.max {|a, b| a.length <=> b.length} # "albatross" ary.max {|a, b| b.length <=> a.length} # "dog" ary = %w[albatross dog horse] ary.max(2) # ["horse", "dog"] ary.max(2){|a, b| a.length <=> b.length} # ["albatross","horse"]
ary = %w(albatross dog horse) a = ary.max do |a, b| x=a.length y=b.length y <=> x end
permutation {|p| block} → ary permutation → Enumerator permutation(n) {|p| block} → ary permutation(n) → Enumerator combination(n) {|c| block} → ary combination(n) → Enumerator
permutation()對數組的元素進行排列,返回排列後的各數組。
combination()對數組做n個元素的組合。
注意,排列、組合的順序不做任何保證。
關於排列和組合的區別:
看下面的示例便可理解:
# permutation()做排列操做 a = [1, 2, 3] a.permutation.to_a # [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] a.permutation(1).to_a # [[1],[2],[3]] a.permutation(2).to_a # [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]] a.permutation(3).to_a # [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] a.permutation(0).to_a # [[]] # one permutation of length 0 a.permutation(4).to_a # [] # no permutations of length 4
# combination()做組合操做 a = [1, 2, 3, 4] a.combination(1).to_a # [[1],[2],[3],[4]] a.combination(2).to_a # [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]] a.combination(3).to_a # [[1,2,3],[1,2,4],[1,3,4],[2,3,4]] a.combination(4).to_a # [[1,2,3,4]] a.combination(0).to_a # [[]] # one combination of length 0 a.combination(5).to_a # [] # no combinations of length 5
當使用了語句塊時,每一個排列後的子數組將傳遞給語句塊的變量。
a = [1, 2, 3, 4] a.combination(3) {|x| p x << "z" } ## 輸出: ## [1, 2, 3, "z"] ## [1, 2, 4, "z"] ## [1, 3, 4, "z"] ## [2, 3, 4, "z"]
repeated_combination(n) {|c| block} → ary repeated_combination(n) → Enumerator repeated_permutation(n) {|p| block} → ary repeated_permutation(n) → Enumerator
重複n個數組自身,並對這n個數組進行排列操做、組合操做。看示例便可明白。
# repeated_combination() a = [1, 2, 3] a.repeated_combination(1).to_a # [[1], [2], [3]] a.repeated_combination(2).to_a # [[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]] a.repeated_combination(3).to_a # [[1,1,1],[1,1,2],[1,1,3],[1,2,2],[1,2,3], # [1,3,3],[2,2,2],[2,2,3],[2,3,3],[3,3,3]] a.repeated_combination(4).to_a # [[1,1,1,1],[1,1,1,2],[1,1,1,3],[1,1,2,2],[1,1,2,3], # [1,1,3,3],[1,2,2,2],[1,2,2,3],[1,2,3,3],[1,3,3,3], # [2,2,2,2],[2,2,2,3],[2,2,3,3],[2,3,3,3],[3,3,3,3]] a.repeated_combination(0).to_a # [[]] # one combination of length 0
# repeated_permutation() a = [1, 2] a.repeated_permutation(1).to_a # [[1], [2]] a.repeated_permutation(2).to_a # [[1,1],[1,2],[2,1],[2,2]] a.repeated_permutation(3).to_a # [[1,1,1],[1,1,2],[1,2,1],[1,2,2], # [2,1,1],[2,1,2],[2,2,1],[2,2,2]] a.repeated_permutation(0).to_a # [[]] # one permutation of length 0
product(other_ary, ...) → new_ary product(other_ary, ...) {|p| block} → ary
將數組和other_ary的各元素進行組合後返回。
若是使用了語句塊,則每一個組合後的子數組都傳遞給語句塊,並返回數組自身(即a.product() {}
時返回a)。
[1,2,3].product([4,5]) # [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]] [1,2].product([1,2]) # [[1,1],[1,2],[2,1],[2,2]] [1,2].product([3,4],[5,6]) # [[1,3,5],[1,3,6],[1,4,5],[1,4,6], # [2,3,5],[2,3,6],[2,4,5],[2,4,6]] [1,2].product() # [[1],[2]] [1,2].product([]) # []
# 使用語句塊形式 a = [1,2,3] sub_a = a.product([4,5]) {|x| p x} p sub_a ## 輸出: =begin [1, 4] [1, 5] [2, 4] [2, 5] [3, 4] [3, 5] [1, 2, 3] =end
rotate(count=1) → new_ary rotate!(count=1) → ary
轉動數組,使得count位置處的元素做爲新數組的第一個元素。帶感嘆號表示原處修改。
a = [ "a", "b", "c", "d" ] a.rotate # ["b", "c", "d", "a"] a # ["a", "b", "c", "d"] a.rotate(2) # ["c", "d", "a", "b"] a.rotate(-3) # ["b", "c", "d", "a"] a = [ "a", "b", "c", "d" ] a.rotate! # ["b", "c", "d", "a"] a # ["b", "c", "d", "a"] a.rotate!(2) # ["d", "a", "b", "c"] a.rotate!(-3) # ["a", "b", "c", "d"]
transpose → new_ary
若是是多維數組,則返回行列轉換後的新數組。若是元素個數不一致,則直接報錯。
a = [[1,2], [3,4], [5,6]] a.transpose # [[1, 3, 5], [2, 4, 6]] [[1,2,3],[3,4],[5,6]].transpose # IndexError
sample → obj sample(random: rng) → obj sample(n) → new_ary sample(n, random: rng) → new_ary
從數組中隨機選擇一個或n個元素。選擇隨機元素的方式是使用隨機的索引進行選取。若是選擇多個隨機元素,則選擇隨機元素的索引位置會保證惟一性,但仍然可能會選中重複元素,由於數組自身可能會包含重複元素。
參數rng
表示指定生成索引隨機數的生成器。
當爲空數組時,第一種形式返回nil,第二種形式返回空數組。
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] a.sample # 7 a.sample(4) # [6, 4, 2, 5]
a.sample(random: Random.new(1)) # 6 a.sample(4, random: Random.new(1)) # [6, 10, 9, 2]
shuffle → new_ary shuffle(random: rng) → new_ary shuffle! → ary shuffle!(random: rng) → ary
打亂數組元素並返回。感嘆號後綴表示原處修改。
rng參數指定生成隨機數的生塵器。
# shuffle() a = [ 1, 2, 3 ] # [1, 2, 3] a.shuffle # [2, 3, 1] a # [1, 2, 3] a.shuffle(random: Random.new(1)) # [1, 3, 2] # shuffle!() a = [ 1, 2, 3 ] # [1, 2, 3] a.shuffle! # [2, 3, 1] a # [2, 3, 1] a.shuffle!(random: Random.new(1)) # [1, 3, 2]
sum(init=0) → number sum(init=0) {|e| expr } → number
返回各元素加法操做之和。例如[e1, e2, e3].sum
返回init + e1 + e2 + e3
。
若是使用了語句塊,則在相加以前,先對各元素執行語句塊。
若是數組爲空,則返回init參數值。
[].sum # 0 [].sum(0.0) # 0.0 [1, 2, 3].sum # 6 [3, 5.5].sum # 8.5 [2.5, 3.0].sum(0.0) {|e| e * e } # 15.25 [Object.new].sum # TypeError
不只限於能夠執行數值相加操做,只要經過init參數顯式指明初始值類型便可:
["a", "b", "c"].sum("") # "abc" [[1], [[2]], [3]].sum([]) # [1, [2], 3]
可是,join()
和flatten()
都比上述方式運行的更快。
["a", "b", "c"].join # "abc" [[1], [[2]], [3]].flatten(1) # [1, [2], 3]
reverse → new_ary reverse! → ary
將數組元素反轉。帶感嘆號表示原處反轉。
# reverse() ["a","b","c"].reverse # ["c","b", a"] [1].reverse # [1] # reverse!() a = ["a","b","c"] a.reverse! # ["c","b","a"] a # ["c","b","a"]
reverse_each {|item| block} → ary reverse_each → Enumerator
相似於each()
,但反向迭代,即從數組尾部開始迭代。
a = [ "a", "b", "c" ] a.reverse_each {|x| print x," "} # 輸出c b a
sort → new_ary sort {|a, b| block} → new_ary sort! → ary sort! {|a, b| block} → ary
對數組元素進行排序,而後返回。帶感嘆號後綴表示原處修改。
當沒有使用語句塊時,排序依據是對各元素使用<=>
進行比較。
當使用了語句塊時,將根據語句塊中指定的依據進行排序。
當兩元素比較是等值的,那麼將沒法保證誰在前、誰在後。
# sort() ary = [ "d", "a", "e", "c", "b" ] ary.sort # ["a","b","c","d","e"] ary.sort {|a, b| a <=> b} # ["a","b","c","d","e"] ary.sort {|a, b| b <=> a} # ["e","d","c","b","a"] # sort!() ary = [ "d", "a", "e", "c", "b" ] ary.sort! # ["a","b","c","d","e"] ary.sort! {|a, b| a <=> b} # ["a","b","c","d","e"] ary.sort! {|a, b| b <=> a} # ["e","d","c","b","a"]
sort_by()取自mix-in的Enumerable。sort_by!()是Array自身所實現的。
sort_by { |obj| block } → array sort_by → an_enumerator sort_by! {|obj| block} → ary sort_by! → Enumerator
按照語句塊中的規則進行排序。默認升序排序。
a = %w(perl shell php python java ruby) a.sort_by {|a| a.length} #=> %w[php java ruby perl shell python] (a.sort_by {|a| a[-1]}).reverse #=> %w[ruby php python perl shell java]
第一個排序語句是按照各元素的長度進行升序排序。
第二個排序語句是按照各元素最後一個字符進行升序排序,而後反轉排序結果。
bsearch {|x| block } → elem bsearch_index {|x| block } → int or nil
二者工做機制徹底一致,均用於二分法查找元素,惟一不一樣的在於返回結果。前者返回容器元素,後者返回對應索引。
二分法算法查找過程略。但對於這裏的兩個方法,頗有必要解釋一番。僅以bsearch()方法用法爲例。
首先要求數組是已排序過的,或者說對於語句塊來講是單調的。
bsearch()通常有兩種用法:查找單個最小元素(find-minimum)、查找範圍內元素(find-any)。
find-minimum(即查找單個元素時),要求語句塊返回true/false。當返回true,則向左繼續,當返回false,則向右繼續。直到沒有元素,才返回最後一個true元素,或一直都沒有true則返回nil。
find-any(即查找範圍元素時),要求語句塊返回負數、正數、0。當返回正數時,向右繼續,當返回負數時,向左繼續,返回0則中止。
find-minimum示例1:不等值判斷
a = [-1, 1, 2, 4, 5] p a.bsearch {|x| x > 2} # 4
此語句中,語句塊首先從數組中取中間的元素(若是是偶數,好比6個元素,則取第4個元素),此處所取元素值爲2。
將其進行x>2
的判斷,返回false,因而向右繼續獲得子數組[4, 5]
。再從中取得中間元素5,5大於2返回true。因而向左繼續,取得元素4,4大於2返回true。無法繼續向左,因此返回最後一次爲true的元素,即4。
再自行考慮與小於2(如0)、大於2(如3)的值比較時,整個過程是如何的?
find-minimum示例2:等值判斷
arr_in = [-1, 1, 2, 4, 5] p arr_in.bsearch { |x| x == -1 } # nil p arr_in.bsearch { |x| x == 1 } # nil p arr_in.bsearch { |x| x == 2 } # 2 p arr_in.bsearch { |x| x == 4 } # nil p arr_in.bsearch { |x| x == 5 } # 5
爲何和數組中的元素比較,有些能返回值,有些卻返回nil?
對於x == -1
和x == 1
和x == 4
的比較。首先取中間元素2,比較結果爲false,因而向右獲得子數組[4, 5]
,從中取中間元素5,結果爲false,繼續往右,可是沒有元素能夠往右了,並且以前一直沒有true的結果,因此返回nil。
同理對於x == 2
的比較。首先取中間元素2,比較結果爲true,因而向左獲得子數組[-1,1]
,取中間元素1,比較結果爲false,因而向右,但沒有元素了,因而返回最後一次的true,即元素2。
對於x == 5
的比較,首先取中間元素2,比較結果爲false,因而向右獲得子數組[4, 5]
,從中取中間元素5,結果爲true,繼續往左,獲得子數組[4]
,因而中間元素4與之比較爲false,繼續向右,但向右已沒有元素,因而返回最後一次爲true的元素,即5。
find-any示例3:返回正、負、0的表達式
a = [-1, 1, 2, 4, 5] a.bsearch {|x| -1 - x} # -1 a.bsearch {|x| 1 - x} # 1 a.bsearch {|x| 2 - x} # 2 a.bsearch {|x| 4 - x} # 4 a.bsearch {|x| 5 - x} # 5 a.bsearch {|x| 3 - x} # nil
對於-1 - x
和1 - x
,首先取中間元素2,返回結果負數,因而向左繼續,獲得子數組[-1, 1]
,取中間元素1,對於1 - x
返回0,因而當即中止並返回,對於-1 - x
返回-2繼續向左獲得[-1]
,取中間元素相減後返回0,因而當即中止並返回-1。
對於2-x
,首先取中間元素2,返回結果0,當即中止並返回2。
對於4-x
和5-x
,首先取中間元素2,返回結果爲正數,因此向右繼續取得子數組[4, 5]
,取中間元素5,對於5-x
當即中止並返回,對於4-x
獲得負數因而向左取得子數組[4]
,最後返回0並中止。
而對於3 - x
,則首先返回1爲正數,向右取子數組[4, 5]
,再次返回負數,因而向左取得[4]
,仍然爲負數,但已無元素可繼續向左,因而返回nil。
find-any示例4:<=>符號的比較
當在bsearch()中使用<=>
符號時,必須將待比較值放在左邊,由於<=>
的操做符兩邊元素的順序很重要。
a = [-1, 1, 2, 4, 5] # 待比較值放左邊,參數放右邊 a.bsearch {|x| -1 <=> x} # -1 a.bsearch {|x| 1 <=> x} # 1 a.bsearch {|x| 2 <=> x} # 2 a.bsearch {|x| 4 <=> x} # 4 a.bsearch {|x| 5 <=> x} # 5 a.bsearch {|x| 3 <=> x} # nil # 待比較值放右邊,參數放左邊 a.bsearch {|x| x <=> -1} # nil a.bsearch {|x| x <=> 1} # nil a.bsearch {|x| x <=> 2} # 2 a.bsearch {|x| x <=> 4} # nil a.bsearch {|x| x <=> 5} # nil
首先分析待比較值放左邊,參數放右邊的狀況。
對於-1 <=> x
和1 <=> x
,首先取中間元素2,比較的返回結果爲-1,因而向左繼續取得子數組[-1, 1]
,繼續取中間元素1,對於1 <=> x
所比較的返回結果0,因而當即中止並返回元素1。對於-1 <=> x
比較的返回結果-1,因而向左繼續取自數組[-1]
,最終比較的返回結果爲0,返回-1元素。
對於2 <=> x
,第一次取中間元素2就獲得0,當即中止並返回。
對於4 <=> x
和5 <=> x
,首先取中間元素2,比較的返回結果爲1,因而向右繼續取得子數組[4, 5]
,繼續取中間元素5,對於5 <=> x
所比較的返回結果0,因而當即中止並返回元素51。對於4 <=> x
比較的返回結果-1,因而向左繼續取自數組[4]
,最終比較的返回結果爲0,返回4元素。
對於3 <=> x
,自行分析。
再分析待比較值放右邊,參數放右邊的狀況。
對於x <=> -1
和x <=> 1
,首先取中間元素2,比較的返回結果爲1,因而向右繼續取得子數組[4, 5]
,到這已經不用再向後分析了,由於它們都大於待比價的值,使得一直向右取子數組,最終致使返回nil。
對於x <=> 2
,第一次取中間元素2就獲得0,當即中止並返回。
對於x <=> 4
和x <=> 5
,首先取中間元素2,比較的返回結果爲-1,因而向右繼續取得子數組[-1, 1]
,到這已經不用再向後分析了,由於它們都小於於待比價的值,使得一直向左取子數組,最終致使返回nil。