Ruby array.each每次返回相同的值

时间:2013-06-02 01:23:40

标签: ruby arrays

我正在使用Ruby和Sinatra设计REST API。我只有一个问题: 我正在尝试迭代从MySQL中选择的一系列帖子。 格式为

[{:post => "Hello, world!", :comments => [{:author => "user1", :content => "Goodbye, world!"}]}, ...]

因此,它是一个带有内容发布和注释的哈希的数组,而注释键有另一个包含注释的作者和内容的数组和哈希值。

我有以下代码从MySQL中提取一系列帖子(在包含哈希的数组中返回),然后迭代这些哈希值。对于数组中的每个哈希,它获取帖子ID并查询MySQL以查找与该帖子相关的任何注释。然后它将帖子和注释推送到一个哈希,这被推送到一个返回的数组。

def get_post(id = 'null', profile = 'null', owner = 'null')
        r = Array.new
        x = Hash.new
        p = self.query("SELECT * FROM `posts` WHERE `id` = '#{id}' OR `post_profile` = '#{profile}' OR `post_owner` = '#{owner}'")
        p.each do |i|
            x[:post] = i
            x[:comments] = self.query("SELECT * FROM `comments` WHERE `post` = '#{i["id"]}'")
            r.push(x)
        end
        return r
end

奇怪的是我可以在循环中使用puts语句,我会得到个别帖子

前:

r.push(x)
    puts x

但是数组(r)只是一遍又一遍地包含相同的数据。对不起这么长的帖子,我只想彻底。

1 个答案:

答案 0 :(得分:2)

您不断将相同的Hash实例推送到阵列上,而不是创建新的哈希值。试试这个:

def get_post(id = 'null', profile = 'null', owner = 'null')
  p = self.query("SELECT * FROM `posts` WHERE `id` = '#{id}' OR `post_profile` = '#{profile}' OR `post_owner` = '#{owner}'")
  p.map do |i|
    {
      post: i,
      comments: self.query("SELECT * FROM `comments` WHERE `post` = '#{i["id"]}'")
    }
  end
end

这样做会循环播放帖子(使用map而不是each,我会在稍后解释一下),并为每个帖子返回 new 哈希由您想要的数据组成。 map方法将循环中的所有返回值收集到一个数组中,因此您不必进行任何手动数组管理。