两个大小相等的集合,例如
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" }
答案 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}