Ruby:映射哈希

时间:2014-01-04 03:24:06

标签: ruby

在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)] }]

5 个答案:

答案 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} }})。