1

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

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

有没有一种方法可以在不必更改数组中的每个项目的情况下完成此操作(例如,通过迭代它并以某种方式添加符号)?或者,如果这太难了,有没有更好的选择?

4

5 回答 5

9

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

fruits_and_calories = { :apple => 100,
                        :banana => 200,
                        :kumquat => 225,
                        :orange => 90}
fruits_and_calories.each do |name, calories| 
  eat(name, calories)
end
于 2009-04-30T17:39:48.700 回答
7

完全不改变数据结构,你可以改变块参数来达到同样的效果:

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

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

于 2009-04-30T18:16:23.200 回答
4

Pesto 的答案(使用哈希)是一个很好的答案,但我想我更喜欢使用 Struct。

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)}
于 2009-04-30T18:08:11.970 回答
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) }
于 2009-04-30T17:25:12.853 回答
0

有什么理由它本身必须是一个数组吗?这似乎是一个哈希,或者一个水果类。

于 2009-04-30T17:30:33.013 回答