当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。