Ruby:如何使用符号表示数组中的内容?

时间:2009-04-30 17:16:51

标签: ruby arrays idioms

我有一个如下所示的数组:

fruits_and_calories = [
  ["apple", 100],
  ["banana", 200],
  ["kumquat", 225],
  ["orange", 90]
]

我还想要在数组的每个元素上调用一个方法:

fruits_and_calories.each do |f| eat(f[0], f[1])

我真的希望能说出类似的话:

fruits_and_calories.each do |f| eat(f[:name], f[:calories])

有没有办法可以在不必更改数组中的每个项目的情况下将其拉出来(例如,通过迭代它并以某种方式添加符号)?或者,如果这太难了,还有更好的选择吗?

5 个答案:

答案 0 :(得分:9)

最好的答案是根本不使用数组,而是使用哈希:

fruits_and_calories = { :apple => 100,
                        :banana => 200,
                        :kumquat => 225,
                        :orange => 90}
fruits_and_calories.each do |name, calories| 
  eat(name, calories)
end

答案 1 :(得分:7)

根本不更改数据结构,您可以更改块参数以实现相同的目的:

fruits_and_calories.each  do |name, calories|  eat(name, calories);  end

这是有效的,因为Ruby会自动将内部数组([“apple”,100]等)扩展到块的参数列表中('do | name,calories | ... end')。这是Ruby从Lisp继承的技巧,称为“解构参数”。

答案 2 :(得分:4)

Pesto的答案(使用哈希)是一个很好的答案,但我认为我更喜欢使用结构。

Fruit = Struct.new(:name, :calories)

fruits = [
  Fruit.new("apple", 100),
  Fruit.new("banana", 200),
  Fruit.new("kumquat", 225),
  Fruit.new("orange", 90)
]

fruits.each {|f| eat(f.name, f.calories)}

这也有助于将eat从名称和卡路里变为采用水果实例:

fruits.each {|f| eat(f)}

答案 3 :(得分:0)

数组总是用数字索引,所以据我所知,使用标准数组是不可能的。

就个人而言,我只是选择使用代码上方的注释来暗示f [0]和f [1]代表什么。

但是,如果你真的想要这样做,我猜一些Array类的鸭子打字工作:


class Array
  def name ; self[0] ; end
  def calories ; self[1] ; end
end

# then call it with:
fruits_and_calories.each {|f| eat(f.name, f.calories) }

答案 4 :(得分:0)

是否有某种原因必须是一个阵列本身?这似乎是一个哈希,或者是一个水果类。