2016-08-09 16 views
2

他のプログラミング言語から来ていますが、私のような多くの人が驚いています。私には簡単な問題があります。私はリストを持っています - 例えば、ユーザー。私はユーザーを繰り返し、いくつかの情報を表示したい。 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 %> 

まず、ユーザーの値がnilであることが判明回している私は、これに困惑してしまったまで非常にシンプル。理由は分かりません。第二に、私はこれについて説明していない。

"user = Enum.at(@users、i)"と<%=ユーザーの違いは何ですか?< - @users%>?後者の場合、ユーザーはゼロではありません。

最後に、リストを通して時間を記録し、少し異なるアクション(上記の例のように新しい行でユーザーを開始するなど)を取る最良の方法は何ですか?

物事を単純にするために、行の最後の「/ div」タグ(リスト内のユーザー数によって異なる)がないかもしれないという事実も無視しました。私は、ただちに問題に焦点を当てるために、その周りに論理を置くことを無視しました。

答えて

4

user = Enum.at(@users, i)<%= for user <- @users %>の違いは何ですか?後者の場合、ユーザーはゼロではありません。

最後の反復ではuser = nilになるはずです。これは、0からlength(@users)までループしているため、最後の反復値はlength(@users)になります。インデックスは0から始まるので、リスト内の最後の有効なインデックスよりも1だけ多くなります。 0からlength(@users) - 1にループする必要があります。 @usersが空の場合は、Enum.to_list(0..-1) #=> [0, -1]と表示されます。

最後に、リストを倍を追跡し、(上記の例のように新しい行にユーザーを開始するように)わずかに異なる行動を取るための最良の方法は何ですか?

Enum.with_indexifを使用します。また、Elixirのlengthは遅い(O(n))操作なので、反復ごとに再計算するのではなく、その値をループの外側にキャッシュするのが最善です。私はまた、"</div>"を第2の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 %> 
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 %> 
0

私は1つの問題は、あなたの代わりに0 to lengthの、0 to length - 1からループに必要なことだと思います。長さが最後の回帰まで繰り返されたので、Enum.at(@users, length)は

関連する問題