将两个集合压缩为哈希的最标准方法是什么?

时间:2013-07-03 04:23:25

标签: ruby

两个大小相等的集合,例如

u = :a, :b, :c
v = 1, 2, 3

可轻松压缩:

u.map.with_index { |e, i| [e, v[i] ] }

但是当有#zip方法时,为什么还要烦恼:

u.zip v

同样,它们可以很容易地压缩成哈希:

Hash[ u.zip v ]

我的问题是,Ruby核心,stdlib或任何着名的宝石都有标准的方法来执行这种频繁的操作吗?我想象的是:

u.hashzip v #=> { a: 1, b: 2, c: 3 }
u.hashzip &:to_s #=> { a: "a", b: "b", c: "c" }

2 个答案:

答案 0 :(得分:2)

Hash[u.zip(v)]是将两个相等大小的数组转换为我见过的哈希的最简洁和最常用的习惯用法。将其与Hash.combine进行比较:

require 'benchmark'
require 'pp'

# From:
#     http://rubydoc.info/gems/hash-utils/2.1.2/Hash#combine-class_method
class Hash
  def self.combine(keys, values)
    result = {}
    keys.each_index do |i|
      result[keys[i]] = values[i]
    end

    return result
  end
end

def zip_method(a, b)
  Hash[a.zip(b)]
end

ALPHA = ('a' .. 'z').to_a * 25
NUMERIC = (0 .. 25).to_a * 25
N = 10_000

puts "N = #{ N }"
puts "Ruby version = " + `ruby -v`

pp Hash.combine(%w[a b c], [1, 2, 3])
pp Hash[%w[a b c].zip([1, 2, 3])]
pp zip_method(%w[a b c], [1, 2, 3])

Benchmark.bm(10) do |x|
  x.report('zip') { N.times { Hash[ALPHA.zip(NUMERIC)] }}
  x.report('zip_method') { N.times { zip_method(ALPHA, NUMERIC) }}
  x.report('combine') { N.times { Hash.combine(ALPHA, NUMERIC) }}
end

有了这些结果:

N = 10000
Ruby version = ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]
{"a"=>1, "b"=>2, "c"=>3}
{"a"=>1, "b"=>2, "c"=>3}
{"a"=>1, "b"=>2, "c"=>3}
                 user     system      total        real
zip          1.990000   0.010000   2.000000 (  1.993747)
zip_method   1.980000   0.000000   1.980000 (  1.990298)
combine      2.130000   0.000000   2.130000 (  2.133492)

我添加zip_method以查看调用该方法会产生什么差异。奇怪的是,它没有任何结果。我可能错过了一些东西。

这类问题已存在一段时间了:http://www.ruby-forum.com/topic/125944

答案 1 :(得分:0)

鉴于在这里温和地鼓励回答自己的问题,我现在已经到了使“hashzip”方法成为我的y_support gem的一部分,重载>>运算符的地步:

require 'y_support/core_ext/array'

x = :a, :b, :c
y = 1, 2, 3

x >> y
#=> {:a=>1, :b=>2, :c=>3}