Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a list item by index in elm?

Tags:

list

elm

I got a list, and now I want the nth item. In Haskell I would use !!, but I can't find an elm variant of that.

like image 725
11684 Avatar asked Apr 21 '14 14:04

11684


3 Answers

Elm added arrays in 0.12.1, and the implementation was massively overhauled in 0.19 to improve correctness and performance.

import Array

myArray = Array.fromList [1..5]

myItem = Array.get 2 myArray

Arrays are zero-indexed. Negative indices are not supported currently (bummer, I know).

Note that myItem : Maybe Int. Elm does everything it can to avoid runtime errors, so out of bounds access returns an explicit Nothing.

If you find yourself looking to index into a list rather than take the head and tail, you should consider using an array.

Array documentation

like image 73
mgold Avatar answered Nov 13 '22 23:11

mgold


There is no equivalent of this in Elm. You could of course implement it yourself.

(Note: This is not a "total" function, so it creates an exception when the index is out of range).

infixl 9 !!
(!!) : [a] -> Int -> a
xs !! n  = head (drop n xs)

A better way would be to define a total function, using the Maybe data type.

infixl 9 !!
(!!) : [a] -> Int -> Maybe a
xs !! n  = 
  if | n < 0     -> Nothing
     | otherwise -> case (xs,n) of
         ([],_)    -> Nothing
         (x::xs,0) -> Just x
         (_::xs,n) -> xs !! (n-1)
like image 14
Daniël Heres Avatar answered Nov 13 '22 22:11

Daniël Heres


I've used this:

(!!): Int -> List a -> Maybe a

(!!) index list =                          -- 3 [ 1, 2, 3, 4, 5, 6 ]

   if  (List.length list) >= index then

        List.take index list               -- [ 1, 2, 3 ]
        |> List.reverse                    -- [ 3, 2, 1 ]
        |> List.head                       -- Just 3
   else 
      Nothing

Of course you get a Maybe and you need to unwrap it when you use this function. There is not guarantee that your list will not be empty, or that you ask for a imposible index (like 1000) - so that's why elm compiler forces you to account for that case.

main = 
let 
  fifthElement = 
    case 5 !! [1,2,3,4,255,6] of  // not sure how would you use it in Haskell?! But look's nice as infix function. (inspired by @Daniël Heres)
      Just a ->
        a
      Nothing ->
        -1
in
    div [] 
        [ text <| toString fifthElement ]         // 255
like image 2
AIon Avatar answered Nov 14 '22 00:11

AIon