您可以将当前方法重写为仅一次通过这样的折叠:
cols : List a -> { col0 : List a, col1 : List a, col2 : List a, col3 : List a } cols list = list |> List.foldl (\x ( i, cols ) -> case modBy 4 i of 0 -> ( i + 1, { cols | col0 = x :: cols.col0 } ) 1 -> ( i + 1, { cols | col1 = x :: cols.col1 } ) 2 -> ( i + 1, { cols | col2 = x :: cols.col2 } ) 3 -> ( i + 1, { cols | col3 = x :: cols.col3 } ) _ -> ( i + 1, cols ) ) ( 0, { col0 = [], col1 = [], col2 = [], col3 = [] } ) |> Tuple.second
这也可以在内部跟踪索引,因此不需要您为其提供索引列表,但是仍然为四列进行了硬编码。如果我们希望能够将其与任意数量的列一起使用,则必须使用可以按顺序容纳任意数量的项目的数据结构。数组非常适合此操作,允许我们使用使用modBy
以下命令计算的索引来更新它:
cols : Int -> List a -> List (List a) cols n list = list |> List.foldl (\x ( i, cols ) -> let index = modBy n i tail = cols |> Array.get index |> Maybe.withDefault [] in ( i + 1, Array.set index (x :: tail) cols ) ) ( 0, Array.repeat n [] ) |> Tuple.second |> Array.toList
然后List.map
,我们可以在view函数中使用它们来渲染它们:
viewItems : Array Item -> Html msg viewItems items = let itemsHtml = Array.map viewItem items |> Array.toList in main_ [ class "section" ] [ Html.div [ class "container" ] [ Html.div [ class "columns" ] (cols 4 itemsHtml |> List.map (Html.div [ class "column" ])) ] ]