Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在elm脚本中将类添加到表的所有列_Elm - Fatal编程技术网

如何在elm脚本中将类添加到表的所有列

如何在elm脚本中将类添加到表的所有列,elm,Elm,elm脚本从后端代码获取csv字符串csv。我想创建一个表,每个单元格的类名应该是列名 表格的行可以从rows=String.split“\n”csv中获得。如果我不需要定义类,可以通过在行上应用双嵌套List.map来创建表。但为了给每个单元格赋予类,我需要保存包含列(或类)名称的行的第一个元素,并将其与剩余的每一行配对。由于elm中没有for循环,我的策略是定义一个递归函数来创建所有tr元素,并使用List.map连接tr元素。此函数的输入是第一行名为names,另一行名为cols。它们都是

elm脚本从后端代码获取csv字符串
csv
。我想创建一个表,每个单元格的类名应该是列名

表格的行可以从
rows=String.split“\n”csv
中获得。如果我不需要定义类,可以通过在
行上应用双嵌套
List.map
来创建表。但为了给每个单元格赋予类,我需要保存包含列(或类)名称的行的第一个元素,并将其与剩余的每一行配对。由于elm中没有for循环,我的策略是定义一个递归函数来创建所有
tr
元素,并使用
List.map
连接
tr
元素。此函数的输入是第一行名为
names
,另一行名为
cols
。它们都是
列表字符串
。每次运行时,它都使用两个列表的头(从
List.head
)创建一个
td
,然后传递两个列表的其余元素(从
List.drop
)进行递归。但我无法连接两个返回的组件

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 
createRow名称cols=
凯科斯
[]->文本“”
_ ->
让
c0=(列表头列)
c=(List.drop 1列)
n0=(列表标题名称)
n=(List.drop 1名称)
在里面

td[][text在递归函数中,您需要传递(部分计算的)结果,以便在每次调用中对其进行修改,并在完成递归后返回。因此,这可能类似于:

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 ])
type alias Csv =
    { headers : List String
    , records : List (List String)
    }
这里还有几个值得注意的变化:

  • 我使用模式匹配从其余的列表中提取
    cols
    列表的头部(也称为尾部)
  • List.head
    返回一个
    可能是一个
    (在本例中,
    a
    字符串
    ),因此我添加了对
    可能的调用。使用默认值
  • 由于
    cols
    是一个
    列表字符串
    ,因此您不需要调用
    toString
    ,并且可以将其直接传递给
    text
  • 第一次调用此函数时,将为
    单元格
    参数传入
    []

首先,我建议您不要手动解析CSV。package manager上有多个CSV解析器,因此我们可以将重点放在如何处理这些值上

是一个选项,但它们在解析后都会为您提供一个
Csv
类型,如下所示:

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 ])
type alias Csv =
    { headers : List String
    , records : List (List String)
    }
正如您所提到的,每行中有多少个值,就有多少个标题(否则CSV将无效)。通过递归拖放/装箱可以完成工作,但我们可以通过依赖列表操作来完成大部分工作,从而更具声明性:

classTable : Csv -> Html msg
classTable csv =
    table []
        (csv.records |> List.map (tableRow csv.headers))


tableRow : List String -> List String -> Html msg
tableRow headers values =
    let
        insertNextCellInRow ( header, value ) row =
            td [ class header ] [ text value ] :: row
    in
    tr []
        (List.map2 Tuple.pair headers values
            |> List.foldr insertNextCellInRow []
        )

注意:
List.foldr
是递归的,用于命令式语言中的循环(“对于此列表中的每个项目,应用此函数并在另一个列表中收集结果”)但是,它不知道传递给它的值的类型,允许我们专注于转换值。

您能给出函数输入和输出的示例吗?您在描述中提到了
tr
s,但代码中没有
tr
s,只有
td