Frage

Ich habe ein Array von Arrays, die wie folgt aussieht:

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

Ich habe auch eine Methode, die ich auf jedem Element des Arrays aufrufen wollen:

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

Ich würde wirklich in der Lage sein möchte, etwas zu sagen wie:

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

Gibt es eine Möglichkeit, dass ich dies, ohne dass aus jedem Elemente im Array ändern ziehen kann (zum Beispiel durch durchlaufen und das Hinzufügen irgendwie die Symbole in)? Oder, wenn das zu hart ist, ist es eine bessere Alternative?

War es hilfreich?

Lösung

Die beste Antwort ist nicht einen Array überhaupt zu verwenden, aber einen Hash zu verwenden:

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

Andere Tipps

Ohne die Datenstruktur überhaupt zu verändern, man konnte den Block Argumente ändern, das Gleiche zu erreichen:

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

Das funktioniert, weil Ruby die inneren Arrays ([ "apple", 100], usw.) in die Argumentliste für den Block ( 'tut | Namen, Kalorie | ... end') automatisch maximiert. Dies ist ein Trick, die Ruby von Lisp geerbt, bekannt als ‚Destrukturierung Argumente‘.

Pesto Antwort (verwenden Sie einen Hash) ist gut, aber ich glaube, ich würde es vorziehen, eine Struct zu verwenden.

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

Dieses eignet sich auch sowohl den Namen und die Kalorien an sich verändernde eat daran, eine Frucht-Instanz unter:

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

Gibt es einen Grund, es muss ein Array, per se? Das scheint zu schreien ein Hash zu sein, oder eine Klasse für Obst.

Ein Array wird immer durch Zahlen indiziert, so weit ich weiß, den Standard-Array es nicht möglich ist.

Persönlich würde ich entscheiden, nur einen Kommentar über den Code für die Verwendung andeuten, was f [0] und f [1] steht.

Wenn Sie aber versessen sind auf es zu tun Ich denke, einige Ente-Eingabe auf die Array-Klasse funktioniert:


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) }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top