Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elm: Split list into multiple lists

Tags:

elm

I'd like to be able to split a list up into multiple lists. I'm assuming this would need to be stored in a tuple - although not completely sure.

Say I have this group of 8 people

users =
  ["Steve", "Sally", "Barry", "Emma", "John", "Gustav", "Ankaran", "Gilly"]

I would like to split them up into a specific amount of groups. For example, groups of 2, 3 or 4 people.

-- desired result

( ["Steve", "Sally", "Barry"]
, ["Emma", "John", "Gustav"]
, ["Ankaran", "Gilly"]
)

Part 2 of this question would be, How would you then iterate and render the results from a tuple of various lengths?

I was playing around with this example, using tuple-map but it seems to only expect a tuple with 2 values.

import Html exposing (..)
import List

data = (
  ["Steve", "Sally", "Barry"]
  , ["Emma", "John", "Gustav"]
  , ["Ankaran", "Gilly"]
  )

renderLI value =
  li [] [ text value ]

renderUL list =
  ul [] (List.map renderLI list)

main =
    div [] (map renderUL data)

-- The following taken from zarvunk/tuple-map for examples sake

{-| Map over the tuple with two functions, one for each
element.
-}
mapEach : (a -> a') -> (b -> b') -> (a, b) -> (a', b')
mapEach f g (a, b) = (f a, g b)

{-| Apply the given function to both elements of the tuple.
-}
mapBoth : (a -> a') -> (a, a) -> (a', a')
mapBoth f = mapEach f f

{-| Synonym for `mapBoth`.
-}
map : (a -> a') -> (a, a) -> (a', a')
map = mapBoth
like image 843
Denim Demon Avatar asked Dec 08 '22 22:12

Denim Demon


1 Answers

I'd like to be able to split a list up into multiple lists. I'm assuming this would need to be stored in a tuple - although not completely sure.

Tuples are fixed in the number of things they can carry. You can't have a function that accepts any size tuple.

It sounds like you'd like something more flexible, like a list of lists. You could define a split function like this:

import List exposing (..)

split : Int -> List a -> List (List a)
split i list =
  case take i list of
    [] -> []
    listHead -> listHead :: split i (drop i list)

Now you've got a function that can split up any size list into a list containing lists of the requested size.

split 2 users == [["Steve","Sally"],["Barry","Emma"],["John","Gustav"],["Ankaran","Gilly"]]
split 3 users == [["Steve","Sally","Barry"],["Emma","John","Gustav"],["Ankaran","Gilly"]]

Your Html rendering now becomes simpler, since you only have to deal with lists of lists:

import Html exposing (..)
import List exposing (..)

split : Int -> List a -> List (List a)
split i list =
  case take i list of
    [] -> []
    listHead -> listHead :: split i (drop i list)

users =
  ["Steve", "Sally", "Barry", "Emma", "John", "Gustav", "Ankaran", "Gilly"]

renderLI value =
  li [] [ text value ]

renderUL list =
  ul [] (List.map renderLI list)

main =
    div [] (map renderUL <| split 3 users)
like image 99
Chad Gilbert Avatar answered Dec 21 '22 19:12

Chad Gilbert