루비 : 기호를 사용하여 어레이에서 물건을 표현하는 방법은 무엇입니까?
문제
다음과 같이 보이는 배열 배열이 있습니다.
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
루비는 내부 어레이 ([ "애플", 100] 등을 자동 확장하여 블록 ( 'do | name, calories | ... end')에 대한 인수 목록에 자동 확장되기 때문에 작동합니다. 이것은 루비가 LISP에서 물려받은 트릭으로, '파괴적인 주장'으로 알려져 있습니다.
페스토의 대답 (해시 사용)은 좋은 것이지만 구조물을 사용하는 것을 선호한다고 생각합니다.
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]의 의미를 힌트하는 것을 선택합니다.
그러나 당신이 지옥에 구부러진다면 배열 클래스에서 오리가 찍는 것 같아요.
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) }