Ruby: Comment utiliser les symboles pour représenter des objets dans un tableau?

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

  •  03-07-2019
  •  | 
  •  

Question

J'ai un tableau de tableaux ressemblant à ceci:

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

J'ai aussi une méthode à invoquer sur chaque élément du tableau:

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

J'aimerais vraiment pouvoir dire quelque chose comme:

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

Existe-t-il un moyen de retirer ceci sans avoir à changer chaque élément du tableau (par exemple, en le parcourant et en y ajoutant en quelque sorte les symboles)? Ou, si c'est trop difficile, existe-t-il une meilleure alternative?

Était-ce utile?

La solution

La meilleure solution consiste à ne pas utiliser de tableau du tout, mais à utiliser un hachage:

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

Autres conseils

Sans changer la structure des données, vous pouvez changer les arguments du bloc pour obtenir le même résultat:

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

Cela fonctionne parce que Ruby étendra automatiquement les tableaux internes (["pomme", 100], etc.) dans la liste des arguments du bloc ("do | name, calories | ... end"). Ruby a hérité de Lisp cette astuce, connue sous le nom d '"arguments de déstructuration".

La réponse au pesto (utiliser un hash) est bonne, mais je pense que je préférerais utiliser un 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)}

Cela se prête également à changer le manger de prendre à la fois le nom et les calories, pour prendre un exemple de fruit:

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

Existe-t-il une raison pour laquelle il doit être un tableau, en soi? Cela semble être un hasch ou une classe pour les fruits.

Un tableau est toujours indexé par des nombres, donc, autant que je sache, l'utilisation du tableau standard n'est pas possible.

Personnellement, je préférerais simplement utiliser un commentaire au-dessus du code pour indiquer ce que f [0] et f [1] signifient.

Mais si vous êtes déterminé à le faire, je suppose que la saisie de canards dans la classe Array fonctionne:


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) }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top