Ricerca…


Osservazioni

L' List ( elenco collegato ) brilla in accesso sequenziale :

  • accedere al primo elemento
  • anteponendo in cima alla lista
  • cancellando dalla parte anteriore della lista

D'altra parte, non è l'ideale per l'accesso casuale (ad esempio ottenere l'ennesimo elemento) e la traversione in ordine inverso , e si potrebbe avere migliore fortuna (e prestazioni) con la struttura dati Array .

Creazione di un elenco per intervallo

0.18.0

Prima di 0.18.0 puoi creare intervalli come questo:

> range = [1..5]
[1,2,3,4,5] : List number
>
> negative = [-5..3]
[-5,-4,-3,-2,-1,0,1,2,3] : List number
0.18.0

In 0.18.0 La sintassi [1..5] è stata rimossa .

> range = List.range 1 5
[1,2,3,4,5] : List number
>
> negative = List.range -5 3
[-5,-4,-3,-2,-1,0,1,2,3] : List number

Gli intervalli creati da questa sintassi sono sempre inclusivi e il passo è sempre 1 .

Creare una lista

> listOfNumbers = [1,4,99]
[1,4,99] : List number
>
> listOfStrings = ["Hello","World"]
["Hello","World"] : List String
>
> emptyList = []   -- can be anything, we don't know yet
[] : List a
>

Sotto la cappa, List ( lista collegata ) è costruita dalla funzione :: (chiamata "contro"), che prende due argomenti: un elemento, noto come la testa, e un elenco (eventualmente vuoto) a cui è preposta la testa.

> withoutSyntaxSugar = 1 :: []
[1] : List number
>
> longerOne = 1 :: 2 :: 3 :: []
[1,2,3] : List number
>
> nonemptyTail = 1 :: [2]
[1,2] : List number
>

List può assumere solo valori di un tipo, quindi qualcosa come [1,"abc"] non è possibile. Se ti serve, usa le tuple.

> notAllowed = [1,"abc"]
==================================== ERRORS ====================================

-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm

The 1st and 2nd elements are different types of values.

8|              [1,"abc"]
               ^^^^^
The 1st element has this type:

    number

But the 2nd is:

    String

Hint: All elements should be the same type of value so that we can iterate
through the list without running into unexpected values.


> 

Ottenere elementi

> ourList = [1,2,3,4,5]
[1,2,3,4,5] : List number
>
> firstElement = List.head ourList
Just 1 : Maybe Int
>
> allButFirst = List.tail ourList
Just [2,3,4,5] : Maybe (List Int)

Questo inserimento nel tipo Maybe verifica a causa del seguente scenario:

Cosa dovrebbe restituire List.head per una lista vuota? (Ricorda, Elm non ha eccezioni o null.)

> headOfEmpty = List.head []
Nothing : Maybe Int
>
> tailOfEmpty = List.tail []
Nothing : Maybe (List Int)
>
> tailOfAlmostEmpty = List.tail [1] -- warning ... List is a *linked list* :)
Just [] : Maybe (List Int)

Trasformare ogni elemento di una lista

List.map : (a -> b) -> List a -> List b è una funzione di ordine superiore che applica una funzione a parametro unico a ciascun elemento di una lista, restituendo una nuova lista con i valori modificati.

import String

ourList : List String
ourList = 
    ["wubba", "lubba", "dub", "dub"]

lengths : List Int
lengths = 
    List.map String.length ourList
-- [5,5,3,3]

slices : List String
slices =
    List.map (String.slice 1 3) ourList
-- ["ub", "ub", "ub", "ub"]

Se è necessario conoscere l'indice degli elementi è possibile utilizzare List.indexedMap : (Int -> a -> b) -> List a -> List b :

newList : List String
newList =
    List.indexedMap (\index element -> String.concat [toString index, ": ", element]) ourList
-- ["0: wubba","1: lubba","2: dub","3: dub"] 

Filtrare un elenco

List.filter : (a -> Bool) -> List a -> List a è una funzione di ordine superiore che accetta una funzione a parametro unico da qualsiasi valore a un valore booleano e applica tale funzione a ogni elemento di una determinata lista, mantenendo solo quegli elementi per i quali la funzione restituisce True on. La funzione che List.filter prende come primo parametro viene spesso definita un predicato .

import String

catStory : List String
catStory = 
    ["a", "crazy", "cat", "walked", "into", "a", "bar"]

-- Any word with more than 3 characters is so long!
isLongWord : String -> Bool
isLongWord string =
    String.length string > 3

longWordsFromCatStory : List String
longWordsFromCatStory = 
    List.filter isLongWord catStory

Valuta questo in elm-repl :

> longWordsFromCatStory
["crazy", "walked", "into"] : List String
>
> List.filter (String.startsWith "w") longWordsFromCatStory
["walked"] : List String

Pattern Matching su un elenco

Possiamo abbinare gli elenchi come qualsiasi altro tipo di dati, sebbene siano un po 'unici, in quanto il costruttore per la creazione di elenchi è la funzione infisso :: . (Vedere l'esempio Creazione di un elenco per ulteriori informazioni su come funziona.)

matchMyList : List SomeType -> SomeOtherType
matchMyList myList = 
    case myList of
        [] -> 
            emptyCase

        (theHead :: theRest) ->
            doSomethingWith theHead theRest

Possiamo abbinare tanti elementi nella lista che vogliamo:

hasAtLeast2Elems : List a -> Bool
hasAtLeast2Elems myList =
    case myList of
        (e1 :: e2 :: rest) -> 
            True
    
        _ -> 
            False

hasAtLeast3Elems : List a -> Bool
hasAtLeast3Elems myList =
    case myList of
        (e1 :: e2 :: e3 :: rest) -> 
            True
    
        _ -> 
            False

Ottenere l'ennesimo elemento dalla lista

List non supporta "l'accesso casuale", il che significa che ci vuole più lavoro per ottenere, diciamo, il quinto elemento dalla lista rispetto al primo elemento, e di conseguenza non c'è alcuna funzione List.get nth list . Uno deve andare dall'inizio ( 1 -> 2 -> 3 -> 4 -> 5 ).

Se hai bisogno dell'accesso casuale, potresti ottenere risultati migliori (e prestazioni) con strutture di dati ad accesso casuale, come Array , dove prendere il primo elemento richiede la stessa quantità di lavoro di prendere, per esempio, il millesimo. (complessità O (1)).

Tuttavia, è possibile (ma scoraggiato) ottenere l'ennesimo elemento:

get : Int -> List a -> Maybe a
get nth list =
    list
        |> List.drop (nth - 1)
        |> List.head

fifth : Maybe Int
fifth = get 5 [1..10]
--    = Just 5

nonexistent : Maybe Int
nonexistent = get 5 [1..3]
--          = Nothing

Di nuovo, questo richiede molto più lavoro, più grande è l' nth argomento.

Ridurre un elenco a un singolo valore

A Elm, funzioni riducenti sono chiamati "pieghe", e ci sono due metodi standard di "piega" valori fino: sulla sinistra, foldl , e da destra, foldr .

> List.foldl (+) 0 [1,2,3]
6 : number

Gli argomenti a foldl e foldr sono:

  • funzione di riduzione : newValue -> accumulator -> accumulator
  • accumulatore valore iniziale
  • elenco da ridurre

Un altro esempio con funzione personalizzata:

type alias Counts =
    { odd : Int
    , even : Int
    }

addCount : Int -> Counts -> Counts
addCount num counts =
    let
        (incOdd, incEven) =
            if num `rem` 2 == 0
                then (0,1)
                else (1,0)
    in
        { counts
            | odd = counts.odd + incOdd
            , even = counts.even + incEven
        }

> List.foldl
      addCount
      { odd = 0, even = 0 }
      [1,2,3,4,5]
{ odd = 3, even = 2 } : Counts

Nel primo esempio sopra il programma va in questo modo:

List.foldl (+) 0 [1,2,3]
3 + (2 + (1 + 0))
3 + (2 + 1)
3 + 3
6
List.foldr (+) 0 [1,2,3]
1 + (2 + (3 + 0))
1 + (2 + 3)
1 + 5
6

Nel caso di una funzione commutativa come (+) non c'è davvero una differenza.

Ma vedi cosa succede con (::) :

List.foldl (::) [] [1,2,3]
3 :: (2 :: (1 :: []))
3 :: (2 :: [1])
3 :: [2,1]
[3,2,1]
List.foldr (::) [] [1,2,3]
1 :: (2 :: (3 :: []))
1 :: (2 :: [3])
1 :: [2,3]
[1,2,3]

Creare una lista ripetendo un valore

> List.repeat 3 "abc"
["abc","abc","abc"] : List String

Puoi dare a List.repeat qualsiasi valore:

> List.repeat 2 {a = 1, b = (2,True)}
[{a = 1, b = (2,True)}, {a = 1, b = (2,True)}]
  : List {a : Int, b : (Int, Bool)}

Ordinamento di una lista

Per impostazione predefinita, List.sort ordina in ordine crescente.

> List.sort [3,1,5]
[1,3,5] : List number

List.sort richiede che gli elementi della lista siano comparable . Ciò significa: String , Char , number ( Int e Float ), List di comparable o tupla comparable .

> List.sort [(5,"ddd"),(4,"zzz"),(5,"aaa")]
[(4,"zzz"),(5,"aaa"),(5,"ddd")] : List ( number, String )

> List.sort [[3,4],[2,3],[4,5],[1,2]]
[[1,2],[2,3],[3,4],[4,5]] : List (List number)

Non è possibile ordinare elenchi di Bool o oggetti con List.sort . Per questo vedi Ordinamento di un elenco con comparatore personalizzato.

> List.sort [True, False]
-- error, can't compare Bools

Ordinamento di un elenco con comparatore personalizzato

List.sortWith consente di ordinare elenchi con dati di qualsiasi forma: lo si fornisce con una funzione di confronto.

compareBools : Bool -> Bool -> Order
compareBools a b =
    case (a,b) of
        (False, True) ->
            LT

        (True, False) ->
            GT

        _ ->
            EQ
        
> List.sortWith compareBools [False, True, False, True]
[False, False, True, True] : List Bool

Inversione di una lista

Nota: questo non è molto efficiente a causa della natura di List (vedere Note sotto). Sarà meglio costruire la lista la via "giusta" dall'inizio piuttosto che costruirla e poi invertirla.

> List.reverse [1,3,5,7,9]
[9,7,5,3,1] : List number

Ordinamento di un elenco in ordine decrescente

Di default, List.sort ordina in ordine crescente, con la funzione di compare .

Esistono due modi per ordinare in ordine decrescente: uno efficiente e uno inefficiente.

  1. Il modo efficace : List.sortWith e una funzione di confronto decrescente.
descending a b =
    case compare a b of
      LT -> GT
      EQ -> EQ
      GT -> LT

> List.sortWith descending [1,5,9,7,3]
[9,7,5,3,1] : List number
  1. Il modo inefficiente (scoraggiato!) : List.sort e quindi List.reverse .
> List.reverse (List.sort [1,5,9,7,3])
[9,7,5,3,1] : List number

Ordinamento di un elenco in base a un valore derivato

List.sortBy consente di utilizzare una funzione sugli elementi e utilizzare il suo risultato per il confronto.

> List.sortBy String.length ["longest","short","medium"]
["short","medium","longest"] : List String
-- because the lengths are: [7,5,6]

Funziona egregiamente con i programmi di accesso ai record:

people =
    [ { name = "John", age = 43 }
    , { name = "Alice", age = 30 }
    , { name = "Rupert", age = 12 }
    ]

> List.sortBy .age people
[ { name = "Rupert", age = 12 }
, { name = "Alice", age = 30 }
, { name = "John", age = 43 }
] : List {name: String, age: number}

> List.sortBy .name people
[ { name = "Alice", age = 30 }
, { name = "John", age = 43 }
, { name = "Rupert", age = 12 }
] : List {name: String, age: number}


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow