圣诞节已通过去,2.6已经发布,如今是时候无情叫卖 2.7 版本的发布页面,这样咱们就能够开始咱们有趣的「关于即将推出的功能」的年度博客传统。git
一般这意味着另外一个 12 月的发布,可是若是它们能在今年年初合并到主干,则有一些方法例子能够更早的制做。github
此次咱们有了新的方法 Enumerable#tally
!ruby
tally
计数:app
[1, 1, 2].tally # => { 1 => 2, 2 => 1 } [1, 1, 2].map(&:even?).tally # => { false => 2, true => 1 }
Ruby 官方测试代码中使用的示例:函数
[1, 2, 2, 3].tally # => { 1 => 1, 2 => 2, 3 => 1 }
没有块(Block),tally
计算 Enumerable 类型中每一个元素的出现次数,若是咱们将它应用于另外一种类型的列表,它可能会更清楚一些:测试
%w(foo foo bar foo baz foo).tally => {"foo"=>4, "bar"=>1, "baz"=>1}
目前 tally_by
还没有被接受到核心,所以要经过函数计算,您将首先使用 map:ui
%w(foo foo bar foo baz foo).map { |s| s[0] }.tally => {“f” => 4, “b” => 2}
目前正在讨论接受此功能,这将产生上述语法:3d
%w(foo foo bar foo baz foo).tally_by { |s| s[0] } => {“f” => 4, “b” => 2}
若是您一直在使用 Ruby,那么您可能已经使用相似其中一些代码来作 tally
相似的上述事情:code
list.group_by { |v| v.something }.transform_values(&:size) list.group_by { |v| v.something }.map { |k, vs| [k, vs.size] }.to_h list.group_by { |v| v.something }.to_h { |k, vs| [k, vs.size] } list.each_with_object(Hash.new(0)) { |v, h| h[v.something] += 1 }
可能还有其余几种变体,但这些是您可能会看到的一些更常见的变体。这是一种很是优雅的方法在 Ruby 语言中缩写很是常见的方言,也是一种很是受欢迎的方法。orm
这种方法有什么做用?好吧,若是咱们要在普通的 Ruby 中实现它,它可能看起来像这样:
module Enumerable def tally_by(&function) function ||= -> v { v } each_with_object(Hash.new(0)) do |value, hash| hash[function.call(value)] += 1 end end def tally tally_by(&:itself) end end
在没有提供函数的状况下,它会经过 itself
有效统计,或者更确切地说是标识函数。
标识函数是返回给定内容的函数。若是你给它 1
,它会返回 1
。若是你给它 true
,它会返回 true
。Ruby 也在一个名为 itself
的方法中使用了这个概念。
本文不会深刻讨论上述代码的做用。第五部分 “Reducing Enumerable” 更详细地介绍了此代码。
Nobu 最近提交了一个 Ruby 核心补丁来添加这个方法:
enum.c: Enumerable#tally · ruby/ruby@673dc51
https://github.com/ruby/ruby/...
它被 Ruby 核心团队接受,名为 tally
:
Feature #11076: Enumerable method count_by - Ruby trunk - Ruby Issue Tracking System
https://bugs.ruby-lang.org/is...
让咱们从这个词的含义开始:
A tally is a record of amounts or numbers which you keep changing and adding to as the activity which affects it progresses.
https://www.collinsdictionary...
这个名字来自哪里?最初提出来的名字是 count_by
,但名称被拒绝,由于它和 count
方法有不一样的返回类型和行为。
在从 Tahoe 地区和 RailsCamp West 回来的车上,咱们(我本身,David,Stephanie 和 Shannon)正在讨论可能备用的名称,试图看看该函数是否能够有不一样的名字。
David 并正式提出 tally
并建议。看起来取名字卡住了,代码已合并到主干中。
如今我在几个会议上发表了演讲,并决定在个人 RubyConf 演讲中的一节中用 tally_by
替代 count_by
。文字版在这里:
Reducing Enumerable — Part Five: Cerulean, Master of Tally By
https://medium.com/@baweaver/...
只是一些有趣的背景故事。
2.7 正在路上,让咱们看看它会带来什么!我很期待看到 Ruby 从这里走出去。