2012-03-05 2 views
1

저는 Ruby를 처음 사용하고 있으며, 단어 배열을 분석 그룹으로 그룹화하는 메소드를 작성하려고합니다. 코드는 다음과 같습니다.Ruby는 어떻게 코드 작업을 주입합니까?

def combine_anagrams(words) 
    dict = words.inject(Hash.new(0)) do |list,ws| 
    key = sort_word(ws) 
    if !list.has_key?(key) 
     list[key] = [] 
    end 
    list[key].push(ws) 
    list    #What is this 
    end 
    return dict.values 
end 

제 질문은 진술 문 list을위한 것입니다. 내가 꺼내면리스트가 해시 대신 배열이됩니다.

답변

1

모든 방법/블록/등. 루비에서 무언가를 반환하고, 초기 return 문이 없으면 메서드/블록/등의 마지막 문이 무엇이든간에. 입니다, 무엇이 반환됩니다.

inject에 전달 된 블록의 마지막 줄이되면 list이 반환됩니다. 제거 할 때 반환 값은 list[key].push(ws)이며, 이는 분명히 원하는 것이 아닙니다.

return 키워드를 사용하면 다른 방법으로 실행될 마지막 명령문이 불필요 할 때도 마찬가지입니다 (여기에는 메서드 끝에있는 return이 포함됨). 비록 어떤 사람들은 무언가를 돌려 보내고 싶지 않을 때라도 그것을 사용하려고한다는 것을 명백히하는 것을 좋아하지만.

관련없는 메모에서 : if !list.has_key?(key)은 다시 쓸 수 있습니다. unless list.has_key?(key). 이 같은

+0

고마워요. Ruby 구문은 정말 이상합니다. D – user1249263

+1

@ user1249263 도움이 되니 기쁩니다. 당신은 새로운 사람이므로 여기에 도움이되는 답변을 upvote (http://stackoverflow.com/faq#howtoask)하고 [귀하의 질문에 가장 잘 맞는 답변을 수락하십시오] (http : // meta .stackexchange.com/a/5235/158402)':)'. –

1

inject 작품 :

final = enumerable.inject(initial_value) do |current_value, iteration| 
    # calculations, etc. here 
    value # next iteration, current_value will be whatever the block returns 
end 

따라서, 귀하의 경우, initial_valueHash.new(0), 또는 대신 nil의 존재하지 않는 키에 대한 기본 값으로 0로 하늘의 해시입니다. 이것은 enumerable의 첫 번째 요소에 대해 inject 블록으로 전달됩니다.

삽입 블록 내에서 key이 이미 해시에 키로 있는지 확인합니다. 그렇지 않은 경우에는 빈 배열과 동일하게 설정하십시오. 두 경우 모두 words (ws)의 현재 반복을 가져 와서 배열로 밀어 넣습니다.

마지막으로 블록은 list의 현재 버전을 반환합니다. 다음에 루프가 enumerable의 요소를 처리하면 inject 블록에 대한 첫 번째 매개 변수 인 current_value이됩니다. 더 간단한 예를 들어

,이 샘플 체크 아웃 : 당신이 (당신의 사건 목록과 WS에서) 그것으로 두 개의 인수를 전달하는 경우

numbers = [1, 2, 3, 4] 
sum = inject(0) do |total, number| # first time, total will be 0 
    total + number # set total next time to be whatever total is now plus the current number 
end 
+1

아, 간단한 예제에서 total + number는 다음 반복에서 current_value가됩니다. 맞습니까? 정말 고마워. – user1249263

+0

정확히! 도와 줘서 기뻐요!^_ ^ –

0

가 분사 방법에 http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-inject

살펴보십시오을 첫 번째 목록은 소위 누적 기 값입니다. 각 반복 단계에서 inject 블록에 의해 리턴되는 값은 목록 변수에 지정됩니다. 따라서 블록에있는 목록의 값을 "목록"누적 변수에 할당하는 데 "#이게 무엇입니까?"라고 주석 처리 한 유일한 단어 "list"가있는 행이 사용됩니다.

0

"list"문은 전체 블록의 반환 값입니다. 줄 : "list [key] = []"은 "list"의 반환 값을 가지므로 if 조건의 반환 값을 'list'로 설정하는 데 다른 줄이 필요하지 않지만 list [key] .push (ws)는 list [key]입니다.우리는 결국 목록의 업데이트 된 값을 얻고 자하므로 매번 블록에서 해당 값을 반환해야하므로 업데이트 된 목록의 추가 처리 작업이 수행되고 다른 작업은 수행되지 않아야합니다.

배경으로 각 루비 행에는 반환 값이 있으므로 블록 또는 함수의 마지막 줄이면 자동으로 전체 블록이나 함수의 반환 값이됩니다.

은 IRB에 다음과 같은 몇 가지 코드를 시도, 더 이것을 이해하려면

a = [1,2,3,4,5] 
b = a.inject(0) {|sum, val| puts sum; puts val; sum + val} 

내부 블록이 세 statememts으로 구성; 마지막 명령문은 합계에 저장되는 블록에 sum + val의 값을 반환하여 다음 반복에서 사용됩니다. 또한

는 다음과 같은 몇 가지 코드를 시도 :

h = {:a => []} 
b = h[:a].push 6 

참조 무엇 B가 평가; 당신의 코드에서 h [: a]에 저장된 배열이 아니라 누적 된 해시가되도록 'b'가 필요합니다.

관련 문제