如何处理数组中的信息?

时间:2013-01-07 23:42:27

标签: ruby-on-rails ruby

我正在尝试学习考拉宝石以将Facebook与我的Ruby on Rails应用程序联系起来。我开始掌握它,但我遇到了一些严重的心理障碍!

def friends
  facebook.fql_query("SELECT uid,username, is_app_user, name, pic_square FROM user WHERE uid IN(SELECT uid2 FROM friend WHERE uid1 = me()) AND is_app_user=1");
rescue Koala::Facebook::APIError => e
  logger.info e.to_s
  nil
end

所以,首先,我使用FQL搜索用户朋友。它会返回一个哈希,其中包含current_user的朋友,登录到应用程序的用户以及与我的应用程序相关联的用户的详细信息。

def friends_realname
  names = friends.select {|f| f["is_app_user"] }.map {|f| f["name"]}
  names.each { |name| puts name}
end

我正在选择上面的“用户的朋友也使用我的应用程序”的名称 - 并将它们映射到一个数组中。这将返回一个数组:["friend1's name", "friend2's name"]

def friends_avatars
  @avatars = friends.select {|f| f["is_app_user"] }.map {|f| f["pic_square"]}
end

我正在尝试执行相同操作,但返回相同用户的个人资料图片的网址。它返回一个数组:

["http://www.example.com/example.jpg", "http://www.example2.com/example2.jpg"]

我想格式化返回的数组中的信息。因此,对于真实姓名,我想返回一个名单列表,而不是返回实际数组。而且,显然对于图像而言,我实际上想要在视图中“放置”这些图像,而不是返回图像网址数组。

我认为我需要遍历每个数组,然后使用each方法对数组中的每个字符串执行某些操作,例如puts img_tag

这样的事情可能吗?:

def friends_avatars
  @avatars = friends.select {|f| f["is_app_user"] }.map {|f| f["pic_square"]}
  @avatars.each { |avatar| puts image_tag "#{avatar}}"}
end

刚才意识到image_tag是一个帮助方法,所以我不能在那里使用它。

我也在视图文件中尝试了这个:

<% for url in @avatars do %>
  <%= puts "#{url}" %>
<% end %>

返回:

undefined method `each' for nil:NilClass

无论何时我尝试在数组中返回字符串,它们只返回一个数组。不确定从哪里开始。

2 个答案:

答案 0 :(得分:1)

app_users = friends.select{ |f| f["is_app_user"] }
@names_and_pictures = app_users.map{ |f| [ f["name"], f["pic_square"] ] }

这会创建一个由两个元素组成的数组,即

[ [ "Bob", "http://foo" ], [ "Jim", "http://bar" ] ]

然后你可以并行迭代这些:

<% @names_and_pictures.each do |name,pic_url| %>
  <li><%=name%><img src="<%=pic_url%>"></li>
<% end %>

请注意,您不在视图中使用puts,因为此函数会向控制台输出信息。相反,您只需使用<%= ... %>强制Ruby代码作为字符串值并将其注入输出中的适当位置。


您的原始代码很好(只要您将代码包装在名称很好的方法中),但确实有点太多了。

def friends_realname
  names = friends.select {|f| f["is_app_user"] }.map {|f| f["name"]}
  names.each { |name| puts name}
end

此处无需puts名称。该方法只会返回正确的值,因为each返回刚刚迭代的项。您的方法可以像以下一样有效地编写:

def friends_realname
  friends.select {|f| f["is_app_user"] }.map {|f| f["name"]}
end

def friends_avatars
  friends.select {|f| f["is_app_user"] }.map {|f| f["pic_square"]}
end

如果您碰巧想要保留这些方法,可以使用Array#zip将两个数组合并为一个:

names   = friends_realname               # One flat array
avatars = friends_avatars                # Another flat array
@names_and_pictures = names.zip(avatars) # An array of two-element arrays

答案 1 :(得分:0)

您对map的调用始终返回一个数组。所以当你这样做时:

@avatars = friends.select {|f| f["is_app_user"] }.map {|f| f["pic_square"]}

你得到一个字符串数组。为了您的观点,您可以这样做:

<% @avatars.each do |url| %>
  <%= puts "#{url}" %>
<% end %>

希望有所帮助