Ruby: Como faço para usar símbolos para representar as coisas de uma matriz?

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

  •  03-07-2019
  •  | 
  •  

Pergunta

Eu tenho uma matriz de matrizes que se parece com isso:

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

Eu também tenho um método que deseja chamar em cada elemento da matriz:

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

Eu realmente gostaria de ser capaz de dizer algo como:

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

Existe uma maneira que eu posso conseguir isso sem ter que alterar cada item na matriz (por exemplo, por iteração através dela e de alguma forma adicionando os símbolos in)? Ou, se isso é muito difícil, há uma alternativa melhor?

Foi útil?

Solução

A melhor resposta é não usar uma matriz em tudo, mas usar um Hash:

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

Outras dicas

Sem mudar a estrutura de dados em tudo, você poderia alterar os argumentos bloco para alcançar a mesma coisa:

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

Isso funciona porque Ruby vai auto-expandem as matrizes internas ([ "alimento", 100], etc) para a lista de argumentos para o bloco ( 'fazer | nome, calorias | ... end'). Este é um truque que Ruby herdou de Lisp, conhecido como 'argumentos desestruturação'.

A resposta de Pesto (use um hash) é uma boa, mas eu acho que eu prefiro usar uma estrutura.

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

Isto também se presta a mudança eat de tomar tanto o nome e calorias, para tomar um exemplo de frutas:

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

Existe alguma razão ele deve ser um array, por si só? Isso parece clamar a ser um hash ou uma classe das Frutas.

Uma matriz é sempre indexados por números, por isso, tanto quanto eu sei usando a matriz padrão que não é possível.

Pessoalmente, eu tinha acabado de opt para usar um comentário acima do código de sugerir o que f [0] e f [1] representa.

Mas se você é o inferno dobrado em fazer isso eu acho que alguma pato-digitando sobre as obras da classe 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) }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top