Ruby:シンボルを使用して配列内の物を表すにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/808069

  •  03-07-2019
  •  | 
  •  

質問

次のような配列の配列があります:

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

配列内の各項目を変更せずにこれを実行する方法はありますか(たとえば、それを繰り返し処理し、何らかの方法でシンボルを追加することによって)。または、それが難しすぎる場合、より良い代替手段はありますか?

役に立ちましたか?

解決

最良の答えは、配列を使用することではなく、ハッシュを使用することです:

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

他のヒント

データ構造をまったく変更せずに、ブロック引数を変更して同じことを実現できます。

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

これは、Rubyが内部配列([" apple&quot ;, 100]など)をブロックの引数リスト( 'do | name、calories | ... end')に自動拡張するために機能します。これは、RubyがLispから継承したトリックで、「引数の破壊」として知られています。

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

それ自体が配列である必要がある 理由はありますか?それはハッシュ、またはフルーツのクラスであると叫ぶようです。

配列は常に数字でインデックス付けされるため、標準配列を使用する限り、不可能です。

個人的には、コードの上のコメントを使用して、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) }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top