I'm just learning Erlang with Chicago Boss and would like to know how could I do something similar to this (in pseudocode):

foreach (items as item)
    if (i % 10 == 0)
        <tr>
    endif
    <td>...</td>
    if (i++ % 10 == 0)
        </tr>
    endif
endforeach

in my template?

有帮助吗?

解决方案

Erlang is functional language so idiomatic way is do it in functional way. We prepare function which will tabular your data first:

-module(tabify).

-export([tabify/2]).

tabify(N, L) when is_list(L), is_integer(N), N > 0 ->
  tabify_(N, L).

tabify_(_, []) -> [];
tabify_(N, L) ->
  {Row, Rest} = row(L, N),
  [Row|tabify_(N, Rest)].

row(L, N) ->
  row(L, N, []).

row([], _, Accu) -> {lists:reverse(Accu), []};
row(Rest, 0, Accu) -> {lists:reverse(Accu), Rest};
row([H|T], N, Accu) -> row(T, N-1, [H|Accu]).

And now we can use it in way:

1> c(tabify).
{ok,tabify}
2> Data = [integer_to_list(X) || X <- lists:seq(1,100)].
["1","2","3","4","5","6","7","8","9","10","11","12","13",
 "14","15","16","17","18","19","20","21","22","23","24","25",
 "26","27","28",
 [...]|...]
3> Table = tabify:tabify(10,Data).
[["1","2","3","4","5","6","7","8","9","10"],
 ["11","12","13","14","15","16","17","18","19","20"],
 ["21","22","23","24","25","26","27","28","29","30"],
 ["31","32","33","34","35","36","37","38","39","40"],
 ["41","42","43","44","45","46","47","48","49","50"],
 ["51","52","53","54","55","56","57","58","59","60"],
 ["61","62","63","64","65","66","67","68","69","70"],
 ["71","72","73","74","75","76","77","78","79","80"],
 ["81","82","83","84","85","86","87","88","89","90"],
 ["91","92","93","94","95","96","97","98","99","100"]]
4> T = [["<tr>", [["<td>", Item, "</td>"] || Item <- Row ], "</tr>"]|| Row <- Table].
[["<tr>",
  [["<td>","1","</td>"],
   ["<td>","2","</td>"],
   ...

And than let io subsystem do the rest. The structure above is well known as iolist and if you put it in any io it will be serialized properly in same way as:

6> iolist_to_binary(T).
<<"<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td></tr><tr><t"...>>

If you have thousands of items in table and efficiency is crucial for you can turn all lists constants into binary. You can also turn into binary data in Data. As last resort you can rewrite tabify/2 and formatting in more efficient but less readable way.

其他提示

If you need to "tabify" a list you can use this function I've just created:

tab_list(List1) ->
    lists:append(
        lists:flatten(
            lists:map(
                fun({Item, Idx}) -> 
                    if 
                        ((Idx - 1) rem 10) == 0 -> lists:concat(["<TR><TD>", Item, "</TD>"]); 
                        (Idx rem 10) == 0 -> lists:concat(["<TD>", Item, "</TD></TR>"]);
                        true -> lists:concat(["<TD>", Item, "</TD>"])
                    end
                end,
            lists:zip(List1, lists:seq(1, length(List1)))
            )
        ),
    if (length(List1) rem 10) == 0 -> ""; true -> "</TR>" end
).

When passed a list like ["a", "b", "c", "d", "e", "f", "g", "h", "i", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "z"] it produces the following results:

"<TR><TD>a</TD><TD>b</TD><TD>c</TD><TD>d</TD><TD>e</TD><TD>f</TD><TD>g</TD><TD>h</TD><TD>i</TD><TD>l</TD></TR><TR><TD>m</TD><TD>n</TD><TD>o</TD><TD>p</TD><TD>q</TD><TD>r</TD><TD>s</TD><TD>t</TD><TD>u</TD><TD>v</TD></TR><TR><TD>z</TD></TR>"

Is this what you need? Just ask if you have any problem!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top