2011-01-10 4 views
0

객체 배열에서 객체 속성의 새 해시를 만들려고합니다. Ruby aaws gem을 통해 Amazon API를 사용하고 있는데 API가 반환하는 배열을 반복하는 방법을 알아내는 데 어려움을 겪고 있으므로 전체 배열이 아니라 속성 만 전달됩니다. 아래 코드를 실행하면 전체 배열을 반환합니다.Ruby에서 객체 배열의 객체 속성 반환

def self.amazon(search) 
    keywords = "#{search}" 
    resp = Amazon::AWS.item_search('Books', { 'Title' => keywords }) 
    items = resp.item_search_response[0].items[0].item 
    items.each do |attribs| 
     a = attribs.item_attributes 
     @results = [] 
     @results << {:label => "#{a.title.to_s[0,85] unless a.title.nil?}", 
       :value => "#{a.title.to_s unless a.title.nil?}", 
       :img => "#{attribs.medium_image.url.to_s unless attribs.medium_image.url.nil?}""" 
       } 

    end 
    end 

루프를 수정해야하지만 틀린 위치를 정확히 알지 못합니다.

답변

0

@results 변수를 만들지 않아도됩니다. 이 같은 Enumerable에서 #지도 방법, 뭔가 :

items.map do |attribs| 
    a = attribs.item_attributes 
    {:label => "#{a.title.to_s[0,85] unless a.title.nil?}", 
      :value => "#{a.title.to_s unless a.title.nil?}", 
      :img => "#{attribs.medium_image.url.to_s unless attribs.medium_image.url.nil?}" 
    } 
end 

Enumerable에서 # 맵은 수신 배열의 각 항목에 제공된 블록을 실행의 반환 값의 배열을 반환합니다. 따라서 원래의 메소드에서 @results를 반환하려는 의도가 있다면지도를 사용하는 것이 더 나을 것입니다.

덧붙여 말하자면, 메소드의 끝에 "return @results"를 넣더라도 매회 @results를 []로 재설정하기 때문에 루프의 마지막 반복에서 계산 된 속성 만 제공합니다 블록이 호출됩니다. 루프 앞에 @results를 []로 초기화하거나 맵을 사용하여 완전히 피하는 방법으로이를 피할 수 있습니다.

2

each 메서드는 작동중인 배열 (이 경우 items)을 반환합니다. 대신 @results를 반환하려는 것 같습니다. 또한 각 패스마다 @ 결과를 []으로 다시 초기화하는 것 같습니다. 루프 외부에서 @results = []을 이동하고 루프 후 명시적인 return @results 또는 (더 관용적으로) @results을 추가하면 트릭을 수행해야합니다.

map 방법을 볼 수도 있습니다. 그것으로, 당신은 단지 이것을 할 수 있습니다 :

@results = items.map do |attribs| 
    a = attribs.item_attributes 
    {:label => "#{a.title.to_s[0,85] unless a.title.nil?}", 
    :value => "#{a.title.to_s unless a.title.nil?}", 
    :img => "#{attribs.medium_image.url.to_s unless attribs.medium_image.url.nil?}" 
    } 
end 

변수를 설정하고 메소드의 마지막 문인 변수를 반환해야합니다. (나중에 설정하기 위해 @results가 필요하다고 가정하고 있습니다. 그렇지 않다면 완전히 생략 할 수 있습니다.)