有效地使用数组和哈希?

时间:2013-03-20 20:36:06

标签: ruby-on-rails ruby arrays hash

我有这些数组:

 @users = [[1,'Mark'],[2,'Bill'],[3,'John']]
 @projects = [[1,'Change the world'],[2,'Build a computer'],[3,'Run in a circle']]
 @points_due = [[1,1,"40"],[1,3,"80"],[2,1,"20"]]

我有一些解决方案,但我正在寻找最有效的方法来迭代所有这些项目,好像结果是通过ActiveRecord给我的。

我想显示带有项目的<UL>和带有用户名的<LI>以及该特定用户的点数。我提出了一些使用injectmap将数组转换为哈希的解决方案,但是,我觉得有更好的方法来做这样的事情。

我想做点什么:

@projects.each do |project|
  <%= project.name %>
  <ul>
  project.each do |user|
    <li><%= user.name %> | <%= user.points_due %></li>
  end
  </ul>
end

1 个答案:

答案 0 :(得分:3)

做一些你正在谈论的事情(迭代模型X,然后为每个模型Y展示一些东西),一个嵌套的.each循环(或多或少类似于你所包含的那个循环)在你的问题)是一个非常标准的方法。如果显示开始变得复杂,您可以将其提取到一个或多个局部图层中。

担心这种或其他方法的表现可能为时过早。操作数据结构的不同方式的性能不会成为页面整体性能的重要因素。一旦你有了工作,看看它是否真的很慢,然后担心如何加快它。

根据您的评论编辑:哈希数组(带键符号)可能比此数据的数组数组更好。不是因为它们的性能更高,而是因为它会使你的代码更容易理解(对你自己来说,即使没有其他任何人可以使用它)。

考虑: 使用AR对象,您将执行以下操作来打印每个项目的名称:

@projects.each do |project|
  puts project.name
end

如果使用哈希模拟此行为:

@projects.each do |project|
  puts project[:name]
end

使用数组:

@projects.each do |project|
  puts project[1]
end

更难记住,你必须确保你的代码以正确的顺序放置属性,或者可能是项目的其他方面,而不是名称。

假设您已经同意我并使用此结构(@projects = [{:title => 'foo', 'id' => 1}, {:title => 'bar', :id => 2}]等),这里有一种方法可以执行您提到的迭代,只需打印出(我相信的)所需的数据 - @points_due中列出的每个用户中包含该点数的点数:

@projects.each do |project|
  puts project[:name]
  @points_due.select{|pd| pd[:project_id] == project[:id] }.each do |project_points|
    user = @users.select{|u| u[:id] == project_points[:user_id]}.first
    puts "#{user[:name]} has #{project_points[:points]} points due on this project."
  end
end

我希望这可以近似你想要的输出,但如果不是,那么使用它作为一个例子应该相当容易 - 明智地使用.select可能会完成它。

编辑第二个:将数组转换为哈希:

@projects_as_arrays = [[1,'Change the world'],[2,'Build a computer'],[3,'Run in a circle']]
@projects_as_hashes = @projects_as_array.map do |p_arr|
  {:id => p_arr[0], :name => p_arr[1]}
end

您应该能够为每个阵列沿着这些常规线做一些事情。