我有这些数组:
@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>
以及该特定用户的点数。我提出了一些使用inject
和map
将数组转换为哈希的解决方案,但是,我觉得有更好的方法来做这样的事情。
我想做点什么:
@projects.each do |project|
<%= project.name %>
<ul>
project.each do |user|
<li><%= user.name %> | <%= user.points_due %></li>
end
</ul>
end
答案 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
您应该能够为每个阵列沿着这些常规线做一些事情。