當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Ruby Enumerable.chunk用法及代碼示例


本文簡要介紹ruby語言中 Enumerable.chunk 的用法。

用法

chunk {|array| ... } → enumerator

返回的枚舉器中的每個元素都是一個 2 元素數組,包括:

  • 塊返回的值。

  • 一個數組 (“chunk”) 包含為其返回該值的元素,以及該塊為其返回相同值的所有以下元素:

以便:

  • 每個與其前身不同的塊返回值開始一個新的塊。

  • 每個與其前身相同的塊返回值繼續相同的塊。

例子:

e = (0..10).chunk {|i| (i / 3).floor } # => #<Enumerator: ...>
# The enumerator elements.
e.next # => [0, [0, 1, 2]]
e.next # => [1, [3, 4, 5]]
e.next # => [2, [6, 7, 8]]
e.next # => [3, [9, 10]]

方法chunk 對於已經排序的枚舉特別有用。此示例計算大量單詞中每個首字母的單詞數:

# Get sorted words from a web page.
url = 'https://raw.githubusercontent.com/eneko/data-repository/master/data/words.txt'
words = URI::open(url).readlines
# Make chunks, one for each letter.
e = words.chunk {|word| word.upcase[0] } # => #<Enumerator: ...>
# Display 'A' through 'F'.
e.each {|c, words| p [c, words.length]; break if c == 'F' }

輸出:

["A", 17096]
["B", 11070]
["C", 19901]
["D", 10896]
["E", 8736]
["F", 6860]

您可以使用特殊符號 :_alone 將元素強製放入其自己的單獨卡盤中:

a = [0, 0, 1, 1]
e = a.chunk{|i| i.even? ? :_alone : true }
e.to_a # => [[:_alone, [0]], [:_alone, [0]], [true, [1, 1]]]

例如,您可以將包含 URL 的每一行放入其自己的塊中:

pattern = /http/
open(filename) { |f|
  f.chunk { |line| line =~ pattern ? :_alone : true }.each { |key, lines|
    pp lines
  }
}

您可以使用特殊符號 :_separatornil 強製忽略元素(不包含在任何塊中):

a = [0, 0, -1, 1, 1]
e = a.chunk{|i| i < 0 ? :_separator : true }
e.to_a # => [[true, [0, 0]], [true, [1, 1]]]

請注意,分隔符確實結束了塊:

a = [0, 0, -1, 1, -1, 1]
e = a.chunk{|i| i < 0 ? :_separator : true }
e.to_a # => [[true, [0, 0]], [true, [1]], [true, [1]]]

例如,svn log 中的連字符序列可以如下消除:

sep = "-"*72 + "\n"
IO.popen("svn log README") { |f|
  f.chunk { |line|
    line != sep || nil
  }.each { |_, lines|
    pp lines
  }
}
#=> ["r20018 | knu | 2008-10-29 13:20:42 +0900 (Wed, 29 Oct 2008) | 2 lines\n",
#    "\n",
#    "* README, README.ja: Update the portability section.\n",
#    "\n"]
#   ["r16725 | knu | 2008-05-31 23:34:23 +0900 (Sat, 31 May 2008) | 2 lines\n",
#    "\n",
#    "* README, README.ja: Add a note about default C flags.\n",
#    "\n"]
#   ...

以空行分隔的段落可以解析如下:

File.foreach("README").chunk { |line|
  /\A\s*\z/ !~ line || nil
}.each { |_, lines|
  pp lines
}

相關用法


注:本文由純淨天空篩選整理自ruby-lang.org大神的英文原創作品 Enumerable.chunk。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。