从Ruby中的对象数组返回对象属性

时间:2011-01-10 15:40:20

标签: ruby-on-rails loops

我正在尝试从对象数组中创建对象属性的新哈希。我通过ruby aaws gem使用Amazon API,我无法弄清楚如何循环API返回的数组,以便它只有属性而不是整个数组。当我运行下面的代码时,它返回整个数组。

   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

我需要修改循环,但我不确定我到底错了。

2 个答案:

答案 0 :(得分:2)

each方法返回它正在操作的数组 - 在本例中为items。看起来你想要返回@results。您似乎也在每次传递时将@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 - 如果不这样做,您可以将其完全删除。)

答案 1 :(得分:0)

您可以避免创建需要使用Enumerable#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

Enumerable #map返回在接收数组中的每个项目上运行提供的块的返回值数组。因此,如果原始方法的意图是返回@results,那么最好使用map。

顺便提一下,即使你在方法的最后放置'return @results',它也只会给出在循环的最后一次迭代中计算的属性,因为你每次将@results重置为[]块被调用。您可以通过在循环之前将@results初始化为[]或完全避免使用map来避免这种情况。