在Python中,我可以创建一个带有列表解析的测试哈希,我会根据一组测试进行检查。我怎样才能在红宝石中实现同样的目标? (我正在使用ruby 1.9.3)
的Python:
test = {x: self.investor.annual_return(x) for x in xrange(1, 6)}
Ruby(尝试):
test = Hash[(1..5).map { |x| [x, @investor.annual_return(x)] }]
答案 0 :(得分:2)
你想要这样的东西:
test = {}
(1..5).map { |i| test[i] = @investor.annual_return(i) }
答案 1 :(得分:2)
我认为您的Ruby代码很好,具体取决于您正在运行的Ruby版本。
从:
开始class Investor
def annual_return(i)
i * i
end
end
investor = Investor.new
在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}
然而,在1.9之前,Hash不会转换包含键/值对的数组数组,所以我们必须得到一点点发烧友,并将flatten
嵌套元素放到一个数组中,然后“爆炸” “哈希的那些元素:
test = Hash[ *(1..5).map { |x| [x, investor.annual_return(x)] }.flatten ]
test # => {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}
结果是一样的,这些日子不那么麻烦。
而且,只是为了展示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]
答案 2 :(得分:1)
你经常看到:
test = (1..5).reduce({}) {|h, x| h[x] = @investor.annual_return(x); h}
但是(从Ruby 1.9开始),许多人更喜欢Enumerable#each_with_object:
test = (1..5).each_with_object({}) {|x, h| h[x] = @investor.annual_return(x)}
部分是因为没有必要将对象h
返回到迭代器,就像Enumerable#reduce(又名inject
)一样。
答案 3 :(得分:0)
如果我理解你正在尝试做什么,你可以试试这个:
{}.tap { |x| (1..5).each do |y| x[y] = @investor.annual_return(i) end }
答案 4 :(得分:0)
您可以通过以下方式轻松完成:
(1..5).map { |x| [x, @investor.annual_return(x)] }.to_h
(文件:Array#to_h
)
Hash[*array]
用于从平面数组([key1, value1, key2, value2, keyN, valueN]
)构造哈希,而Array#to_h
用于从键值对数组构造哈希({{1} }})。