来自其他编程语言,像我这样的很多人会感到惊讶。我有一个简单的问题。我有一个列表 - 比如用户。我想遍历用户并显示一些信息。很简单,直到我被这个难倒:
使用eex模板,我试图这样做:
<%= for i <- 0..length(@users) do %>
<% user = Enum.at(@users) %>
<!-- every third user, I need to display on a new "row" -->
<%= if rem(i,3) == 0 do %>
<div class="row">
<% end %>
<!-- display user information - like user name -->
<%= user.name %>
<!-- then close out the "row" tag if we are due for starting another on the next iteration -->
<%= if rem(i+1,3) == 0 do %>
<div class="row">
<% end %>
<% end %>
首先,用户价值为零。不知道为什么。其次,我对此没有解释。
&#34; user = Enum.at(@users,i)&#34;之间有什么区别?和&lt;%= for user&lt; - @users%&gt;?在后一种情况下,用户不是零。
最后,通过列表跟踪时间的最佳方法是什么,并采取稍微不同的操作(例如在上面的示例中在新行上启动用户)?
为了简单起见,我也忽略了这样一个事实,即我们可能没有最终结束&#34; / div&#34;行的标记(取决于列表中的用户数)。我忽略了解决这个问题只是为了关注手头的问题。
答案 0 :(得分:5)
user = Enum.at(@users, i)
和<%= for user <- @users %>
之间有什么区别?在后一种情况下,用户不是零。
您应该在最后一次迭代中获得user = nil
。这是因为您从0
循环到length(@users)
,最后一次迭代值将是length(@users)
,它比列表中的最后一个有效索引多1个索引是基于0的。您应该从0
循环到length(@users) - 1
。请注意,如果@users
为Enum.to_list(0..-1) #=> [0, -1]
为空,则会导致问题。
最后,通过列表跟踪时间的最佳方法是什么,并采取稍微不同的操作(例如在上面的示例中在新行上启动用户)?
我会使用Enum.with_index
和if
。此外,Elixir中的length
是一个缓慢的(O(n)
)操作,因此最好将其值缓存在循环之外,而不是在每次迭代时重新计算它。我还认为您打算在第二个"</div>"
中打印if
。这是最终的代码:
<% users_length = length(@users) %>
<%= for {user, i} <- Enum.with_index(@users) %>
<%= if rem(i, 3) == 0, do: ~s|<div class="row"| %>
<%= user.name %>
<%= if rem(i + 1, 3) == 0 || i + 1 == users_length, do: "</div>" %>
<% end %>
答案 1 :(得分:0)
我最终使用了Enum.with_index(@users),这也给了我理解中的索引,但我仍然想从一些专家那里了解上面看到的行为。为了他人的利益,这里是我提出的解决方案(也许有更好的解决方案。很想听)
<%= for {user, i} <- Enum.with_index(@users) do %>
<!-- every third user, I need to display on a new "row" -->
<%= if rem(i,3) == 0 do %>
<div class="row">
<% end %>
<!-- display user information - like user name -->
<%= user.name %>
<!-- then close out the "row" tag if we are due for starting another on the next iteration -->
<%= if rem(i+1,3) == 0 || (i+1) > length(@users) do %>
<div class="row">
<% end %>
<% end %>
答案 2 :(得分:0)
我认为一个问题是你需要从0 to length - 1
而不是0 to length
循环。因为你循环到最后一次递归,Enum.at(@users, length
)正在给nil