2011-01-10 17 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変数の作成を避けることができます。列挙#マップ方法、このような何か:

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を返すことになっている場合は、マップを使用するほうがよいでしょう。

ちなみに、メソッドの最後に「return @results」を入れても、毎回@resultsを[]にリセットするため、ループの最後の反復で計算された属性しか与えられませんブロックが呼び出されます。ループの前に@resultsを[]に初期化するか、mapを使用して完全に避けることで回避できます。

2

eachメソッドは、操作していた配列(この場合はitems)を返します。代わりに@resultsを返すように見えます。また、各パスで@retalsを[]に初期化しているようです。 @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を設定する必要があると仮定しています。そうしないと、完全に除外することができます)。

関連する問題