我正在尝试从对象数组中创建对象属性的新哈希。我通过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
我需要修改循环,但我不确定我到底错了。
答案 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来避免这种情况。