要素とその個数をペアにしたハッシュを求めるコードが試行錯誤ののちにだんだん読みやすくなっていく例

次の配列があったとして、

```rb
a = [:c, :b, :c, :c, :a, :b]
```

要素とその個数をペアにしたハッシュを求めるコードが試行錯誤ののちにだんだん読みやすくなっていく例です。(※主観です)

```rb
h = {}; a.each { |e| h[e] = a.count(e) }; h                # => {:c=>3, :b=>2, :a=>1}
h = {}; a.each { |e| h[e] ||= a.count(e) }; h              # => {:c=>3, :b=>2, :a=>1}
h = {}; a.uniq.each { |e| h[e] = a.count(e) }; h           # => {:c=>3, :b=>2, :a=>1}
h = {}; a.each {|e| h[e] = (h[e] || 0) + 1 }; h            # => {:c=>3, :b=>2, :a=>1}
h = {}; a.each {|e| h[e] = h.fetch(e, 0) + 1 }; h          # => {:c=>3, :b=>2, :a=>1}
h = {}; a.each {|e| h[e] = h.fetch(e) { 0 } + 1 }; h       # => {:c=>3, :b=>2, :a=>1}
h = {}; a.each {|e| h[e] = h[e].to_i.next }; h             # => {:c=>3, :b=>2, :a=>1}
h = Hash.new(0); a.each { |e| h[e] += 1 }; h               # => {:c=>3, :b=>2, :a=>1}
Hash.new(0).tap { |h| a.each { |e| h[e] += 1 } }           # => {:c=>3, :b=>2, :a=>1}
Hash[*a.flat_map { |e| [e, a.count(e)] }]                  # => {:c=>3, :b=>2, :a=>1}
a.zip(a.collect { |e| a.count(e) }).to_h                   # => {:c=>3, :b=>2, :a=>1}
a.map { |e| [e, a.count(e)] }.to_h                         # => {:c=>3, :b=>2, :a=>1}
a.uniq.map { |e| [e, a.count(e)] }.to_h                    # => {:c=>3, :b=>2, :a=>1}
a.each_with_object(Hash.new(0)) { |e, m| m[e] += 1 }       # => {:c=>3, :b=>2, :a=>1}
a.each_with_object({}) { |e, m| m[e] = (m[e] || 0) + 1 }   # => {:c=>3, :b=>2, :a=>1}
a.inject(Hash.new(0)) { |a, e| a[e] += 1; a }              # => {:c=>3, :b=>2, :a=>1}
a.inject(Hash.new(0)) { |a, e| a.tap { |a| a[e] += 1 } }   # => {:c=>3, :b=>2, :a=>1}
a.inject({}){|a, e| a.merge(e => 1) { |_, a, b| a + b } }  # => {:c=>3, :b=>2, :a=>1}
a.group_by{|e|e}.collect { |k, v| [k, v.count] }.to_h      # => {:c=>3, :b=>2, :a=>1}
a.group_by{|e|e}.inject({}){|a,(k,v)|a.merge(k => v.size)} # => {:c=>3, :b=>2, :a=>1}
a.group_by{|e|e}.transform_values { |e| e.size }           # => {:c=>3, :b=>2, :a=>1}
a.group_by(&:itself).transform_values(&:size)              # => {:c=>3, :b=>2, :a=>1}
a.tally                                                    # => {:c=>3, :b=>2, :a=>1}
```

ついでにそれぞれの速度は次のようになりました。

```rb
RUBY_VERSION                    # => "2.7.0"
require "active_support/core_ext/benchmark"
def _; "%7.2f ms" % Benchmark.ms { 50_0000.times { yield } } end
_ { h = {}; a.each { |e| h[e] = a.count(e) }; h                } # => " 528.82 ms"
_ { h = {}; a.each { |e| h[e] ||= a.count(e) }; h              } # => " 437.72 ms"
_ { h = {}; a.uniq.each { |e| h[e] = a.count(e) }; h           } # => " 408.69 ms"
_ { h = {}; a.each {|e| h[e] = (h[e] || 0) + 1 }; h            } # => " 371.57 ms"
_ { h = {}; a.each {|e| h[e] = h.fetch(e, 0) + 1 }; h          } # => " 412.14 ms"
_ { h = {}; a.each {|e| h[e] = h.fetch(e) { 0 } + 1 }; h       } # => " 475.63 ms"
_ { h = {}; a.each {|e| h[e] = h[e].to_i.next }; h             } # => " 529.86 ms"
_ { h = Hash.new(0); a.each { |e| h[e] += 1 }; h               } # => " 418.89 ms"
_ { Hash.new(0).tap { |h| a.each { |e| h[e] += 1 } }           } # => " 452.42 ms"
_ { Hash[*a.flat_map { |e| [e, a.count(e)] }]                  } # => " 835.85 ms"
_ { a.zip(a.collect { |e| a.count(e) }).to_h                   } # => " 934.52 ms"
_ { a.map { |e| [e, a.count(e)] }.to_h                         } # => " 685.76 ms"
_ { a.uniq.map { |e| [e, a.count(e)] }.to_h                    } # => " 510.16 ms"
_ { a.each_with_object(Hash.new(0)) { |e, m| m[e] += 1 }       } # => " 503.50 ms"
_ { a.each_with_object({}) { |e, m| m[e] = (m[e] || 0) + 1 }   } # => " 452.22 ms"
_ { a.inject(Hash.new(0)) { |a, e| a[e] += 1; a }              } # => " 522.28 ms"
_ { a.inject(Hash.new(0)) { |a, e| a.tap { |a| a[e] += 1 } }   } # => " 761.82 ms"
_ { a.inject({}){|a, e| a.merge(e => 1) { |_, a, b| a + b } }  } # => "1017.48 ms"
_ { a.group_by{|e|e}.collect { |k, v| [k, v.count] }.to_h      } # => " 866.90 ms"
_ { a.group_by{|e|e}.inject({}){|a,(k,v)|a.merge(k => v.size)} } # => "1075.56 ms"
_ { a.group_by{|e|e}.transform_values { |e| e.size }           } # => " 541.91 ms"
_ { a.group_by(&:itself).transform_values(&:size)              } # => " 689.96 ms"
_ { a.tally                                                    } # => " 260.09 ms"
```

バージョン毎の速度比較

|   2.4.1 |  2.6.5 |   2.7.0 |
|--------: |-------: |--------: |
| 1034.64 | 487.52 |  528.82 |
|  826.21 | 421.96 |  437.72 |
|  950.99 | 382.07 |  408.69 |
|  580.79 | 366.15 |  371.57 |
|  626.53 | 393.59 |  412.14 |
|  697.68 | 451.79 |  475.63 |
|  694.42 | 494.54 |  529.86 |
|  617.90 | 395.69 |  418.89 |
|  644.93 | 417.29 |  452.42 |
| 1406.28 | 764.19 |  835.85 |
| 1499.53 | 907.43 |  934.52 |
| 1238.92 | 652.00 |  685.76 |
| 1006.41 | 490.25 |  510.16 |
|  724.30 | 472.74 |  503.50 |
|  686.70 | 451.96 |  452.22 |
|  733.23 | 477.62 |  522.28 |
|  944.87 | 667.43 |  761.82 |
| 4706.51 | 889.69 | 1017.48 |
| 1290.49 | 772.25 |  866.90 |
| 3063.37 | 953.74 | 1075.56 |
| 1016.31 | 551.76 |  541.91 |
| 1021.88 | 607.18 |  689.96 |
|         |        |  260.09 |