The elm scripts gets a csv string csv
from backend code. I want to create a table and the class name of each cell should be the column name.
The rows of the table can be obtained from rows = String.split "\n" csv
. If I don't need to define classes, a table can be created by applying doubly nested List.map
on rows
. But in order to give class to each cell, I need to save the first element of row which contains the column (or class) names and pair it with each of the remaining rows. Since there is no for loop in elm, my strategy is to define a recursive function to create all tr
elements and concatenate the tr
elements using List.map
. The input of this function is the first row called names
and another row called cols
. They are both List String
. Each time it runs, it creates a td
using the heads (from List.head
) of the two Lists and then pass the remaining elements of the two lists (from List.drop
) for recursion. But I couldn't concatenate the two returned components.
createRow names cols =
case cols of
[] -> text ""
_ ->
let
c0 = (List.head cols)
c = (List.drop 1 cols)
n0 = (List.head names)
n = (List.drop 1 names)
in
td [] [text <| toString <| c0]
, createRow n c
What should I put in the in
block? Or is there a better way to achieve my purpose?
In a recursive function, you need to pass the (partially-computed) result along, so that you can modify it in each call, and return it once you've finished recursing. So that might look something like this:
createRow : List String -> List String -> List (Html msg) -> List (Html msg)
createRow names cols cells =
case cols of
[] -> cells
col :: remainingCols ->
let
name =
names
|> List.head
|> Maybe.withDefault ""
remainingNames = List.drop 1 names
cell =
td [class name] [text col]
in
createRow remainingNames remaningCols (cells ++ [ cell ])
A couple of other notable changes here:
cols
list from the rest (also called the tail)List.head
returns a Maybe a
(in this case, a
is String
), so I've added a call to Maybe.withDefault
cols
is a List String
, you don't need to call toString
and can pass it directly to text
[]
for the cells
argument