[英]Ruby: Mapping a Hash
In Python, I can create a test hash with list comprehension that I check against a suite of test(s). 在Python中,我可以使用列表理解功能创建一个测试哈希,并对照一系列测试进行检查。 How can I achieve the same thing in ruby?
如何在红宝石中实现同一目标? (I'm running on ruby 1.9.3)
(我在运行ruby 1.9.3)
Python: 蟒蛇:
test = {x: self.investor.annual_return(x) for x in xrange(1, 6)}
Ruby (attempt): Ruby(尝试):
test = Hash[(1..5).map { |x| [x, @investor.annual_return(x)] }]
You want something like: 您想要类似的东西:
test = {}
(1..5).map { |i| test[i] = @investor.annual_return(i) }
I think your Ruby code is fine, depending on what version of Ruby you're running. 我认为您的Ruby代码很好,具体取决于您所运行的Ruby版本。
Starting with: 从...开始:
class Investor
def annual_return(i)
i * i
end
end
investor = Investor.new
In Ruby 1.9+, this will work: 在Ruby 1.9+中,它将起作用:
test = Hash[ (1..5).map { |x| [x, investor.annual_return(x)] } ]
test # => {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}
However, prior to 1.9, Hash wouldn't convert an array of arrays containing key/value pairs, so we had to get a bit fancier, and flatten
the nested elements into a single array, then "explode" those elements for Hash: 但是,在1.9之前的版本中,Hash不会转换包含键/值对的数组的数组,因此我们不得不花一些心思,将嵌套的元素
flatten
为单个数组,然后为Hash“分解”这些元素:
test = Hash[ *(1..5).map { |x| [x, investor.annual_return(x)] }.flatten ]
test # => {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}
The result is the same, it's just less hassle these days. 结果是一样的,这几天不再那么麻烦。
And, just to show what Ruby does as we build a hash this way: 而且,只是为了展示Ruby在我们以这种方式构建哈希表时的作用:
(1..5).map { |x| [x, investor.annual_return(x)] }
# => [[1, 1], [2, 4], [3, 9], [4, 16], [5, 25]]
(1..5).map { |x| [x, investor.annual_return(x)] }.flatten
# => [1, 1, 2, 4, 3, 9, 4, 16, 5, 25]
You often see: 您经常看到:
test = (1..5).reduce({}) {|h, x| h[x] = @investor.annual_return(x); h}
but (since Ruby 1.9) many prefer Enumerable#each_with_object : 但是(自Ruby 1.9起)许多人更喜欢Enumerable#each_with_object :
test = (1..5).each_with_object({}) {|x, h| h[x] = @investor.annual_return(x)}
in part because there is no need to return the object h
to the iterator, as there is with Enumerable#reduce (aka inject
). 部分原因是不需要像Enumerable#reduce (又称为
inject
)那样将对象h
返回给迭代器。
如果我正确理解您要执行的操作,则可以尝试以下操作:
{}.tap { |x| (1..5).each do |y| x[y] = @investor.annual_return(i) end }
You can do it easily with: 您可以轻松地做到这一点:
(1..5).map { |x| [x, @investor.annual_return(x)] }.to_h
(Doc: Array#to_h
) (文档:
Array#to_h
)
Hash[*array]
is used to construct a hash from a flat array ( [key1, value1, key2, value2, keyN, valueN]
), whereas Array#to_h
is used to construct a hash from an array of key-value pairs ( [ [key1, value1], [key2, value2], [keyN, valueN] ]
). Hash[*array]
用于从平面数组( [key1, value1, key2, value2, keyN, valueN]
)构造哈希,而Array#to_h
用于从键-值对数组构造哈希( [ [key1, value1], [key2, value2], [keyN, valueN] ]
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.