Udostępnij za pośrednictwem


List (F#)

Lista F# jest uporządkowaną serię niezmienne elementy tego samego typu.

Tworzenie i Inicjowanie listy

Wystawiając jawnie układ elementów, oddzielone średnikami i ujęty w nawiasy kwadratowe, jak pokazano w poniższym wierszu kodu, można zdefiniować listę.

let list123 = [ 1; 2; 3 ]

Można również umieścić podziałów między elementami, w którym to przypadku średnikami są opcjonalne.Składnia ten ostatni może spowodować czytelność kodu wyrażeń inicjowania elementu są dłuższe lub gdy chcesz dołączyć komentarz dla każdego elementu.

let list123 = [
    1
    2
    3 ]

Normalnie wszystkie elementy listy muszą być tego samego typu.Wyjątek stanowi, że listy, w której elementy są określone, typ podstawowy może mieć elementów, które są uzyskane typów.Zatem następujące jest do przyjęcia, ponieważ obie Button i CheckBox pochodzić od Control.

let myControlList : Control list = [ new Button(); new CheckBox() ]

Elementy listy można również zdefiniować przy użyciu zakresu, wskazane przez rozdzielone operatorem zakres liczb całkowitych (..), jak pokazano w poniższym kodzie.

let list1 = [ 1 .. 10 ]

Można także zdefiniować listę za pomocą pętli konstrukcji, jak w poniższym kodzie.

let listOfSquares = [ for i in 1 .. 10 -> i*i ]

Pusta lista jest określony przez parę nawiasów kwadratowych z nic w między nimi.

// An empty list.
let listEmpty = []

Wyrażenie sekwencji można również użyć do utworzenia listy.Zobacz "Sekwencji określeń" w sekwencji.Na przykład poniższy kod tworzy listę kwadratów liczb całkowitych od 1 do 10.

let squaresList = [ for i in 1 .. 10 -> i * i ]

Operatory służące do pracy z listami

Można dołączyć elementy do listy przy użyciu :: operatora (wad).If list1 is [2; 3; 4], the following code creates list2 as [100; 2; 3; 4].

let list2 = 100 :: list1

Można łączyć listy, które mają zgodne typy za pomocą @ operatora, jak w poniższym kodzie.If list1 is [2; 3; 4] and list2 is [100; 2; 3; 4 ], this code creates list3 as [2; 3; 4; 100; 2; 3; 4].

let list3 = list1 @ list2

Funkcje do wykonywania operacji na listach są dostępne w listy Moduł.

Ponieważ listy F# są niezmienne, wszystkie operacje modyfikowania wygenerować nowe listy zamiast modyfikować istniejące listy.

F# list są implementowane jako listy pojedynczo łączone, co oznacza, że operacje, które dostęp jedynie głowy listy są O(1), oraz dostęp do elementu jest O (n).

Właściwości

Typ listy obsługuje następujące właściwości:

Właściwość

Typ

Opis

Szef

'T

Pierwszy element.

Pusty

'T list

Właściwość statyczne, która zwraca pustą listę odpowiedniego typu.

Funkcja IsEmpty

bool

trueJeśli lista nie zawiera żadnych elementów.

Element

'T

Element pod określonym indeksem (od zera).

Długość

int

Liczba elementów.

Ogon

'T list

Lista bez pierwszego elementu.

Poniżej przedstawiono kilka przykładów użycia tych właściwości.

let list1 = [ 1; 2; 3 ]

// Properties
printfn "list1.IsEmpty is %b" (list1.IsEmpty)
printfn "list1.Length is %d" (list1.Length)
printfn "list1.Head is %d" (list1.Head)
printfn "list1.Tail.Head is %d" (list1.Tail.Head)
printfn "list1.Tail.Tail.Head is %d" (list1.Tail.Tail.Head)
printfn "list1.Item(1) is %d" (list1.Item(1))

Korzystanie z list

Programowanie z listy umożliwia wykonywanie złożonych operacji z niewielkiej ilości kodu.W tej sekcji opisano typowe operacje na listach, które są ważne dla programowania funkcjonalności.

Dd233224.collapse_all(pl-pl,VS.110).gifRekursja z listami

Listy są dostosowane do rekurencyjne techniki programowania.Należy wziąć pod uwagę operację, która musi być wykonana na każdy element listy.Można zrobić to rekursywnie działających na głowie listy i następnie przekazując ogon jest mniejsze listy, która składa się z oryginalnej listy bez pierwszego elementu listy, z powrotem do następnego poziomu rekurencji.

Aby napisać funkcji rekurencyjnej, można użyć operatora wad (::) w dopasowywania do wzorca, który umożliwia oddzielenia głowy listę z ogona.

Poniższy przykład kodu pokazuje, jak używać wzorców pasujących do realizacji funkcji rekurencyjnej, która wykonuje operacje na liście.

let rec sum list =
   match list with
   | head :: tail -> head + sum tail
   | [] -> 0

Poprzedni kod działa dobrze dla małych list, ale dla większych list można przepełnienia stosu.Poniższy kod zwiększa się na ten kod przy użyciu argumentu akumulator, standardowa metoda do pracy z funkcjami cykliczne.Użycie argumentu akumulator sprawia, że rekurencyjne ogona funkcja, która pozwala zaoszczędzić miejsce na stosie.

let sum list =
   let rec loop list acc =
       match list with
       | head :: tail -> loop tail (acc + head)
       | [] -> acc
   loop list 0

Funkcja RemoveAllMultiples jest funkcji rekurencyjnej, który ma dwie listy.Pierwsza lista zawiera liczby, w których wielokrotności zostaną usunięte, a druga lista znajduje się lista, z którego chcesz usunąć numery.Kod w poniższym przykładzie używa tej funkcji rekurencyjnej Aby wyeliminować wszystkie non Premier liczby z listy, pozostawiając listę numerów prime w wyniku.

let IsPrimeMultipleTest n x =
   x = n || x % n <> 0

let rec RemoveAllMultiples listn listx =
   match listn with
   | head :: tail -> RemoveAllMultiples tail (List.filter (IsPrimeMultipleTest head) listx)
   | [] -> listx


let GetPrimesUpTo n =
    let max = int (sqrt (float n))
    RemoveAllMultiples [ 2 .. max ] [ 1 .. n ]

printfn "Primes Up To %d:\n %A" 100 (GetPrimesUpTo 100)

Produkcja jest w następujący sposób:

Primes Up To 100:
[2; 3; 5; 7; 11; 13; 17; 19; 23; 29; 31; 37; 41; 43; 47; 53; 59; 61; 67; 71; 73; 79; 83; 89; 97]

Funkcje modułu

Listy Moduł zawiera funkcje, które uzyskują dostęp do elementów listy.Elementu head to najszybszy i najłatwiejszy dostęp.Należy użyć właściwości Head lub funkcji modułu List.head.Ogon listę można uzyskać dostęp za pomocą ogona właściwość lub List.tail funkcji.Aby znaleźć element przez indeks, użyj List.nth funkcji.List.nthPrzechodzi listy.Dlatego też O (n).Jeśli korzysta z kodu List.nth często, warto rozważyć użycie tablicy zamiast na liście.Dostęp do elementu w tablicach jest O(1).

Dd233224.collapse_all(pl-pl,VS.110).gifOperacje logiczne na listach

List.isEmpty funkcja określa, czy lista zawiera wszystkie elementy.

List.exists funkcja stosuje się wartość logiczną test, aby elementy listy i zwraca true , jeżeli jakikolwiek element spełnia badania.List.exists2 jest podobny, ale działa na pary kolejnych elementów w obu list.

Poniższy kod demonstruje użycie List.exists.

// Use List.exists to determine whether there is an element of a list satisfies a given Boolean expression.
// containsNumber returns true if any of the elements of the supplied list match 
// the supplied number.
let containsNumber number list = List.exists (fun elem -> elem = number) list
let list0to3 = [0 .. 3]
printfn "For list %A, contains zero is %b" list0to3 (containsNumber 0 list0to3)

Produkcja jest w następujący sposób:

For list [0; 1; 2; 3], contains zero is true

Poniższy przykład ilustruje użycie List.exists2.

// Use List.exists2 to compare elements in two lists.
// isEqualElement returns true if any elements at the same position in two supplied
// lists match.
let isEqualElement list1 list2 = List.exists2 (fun elem1 elem2 -> elem1 = elem2) list1 list2
let list1to5 = [ 1 .. 5 ]
let list5to1 = [ 5 .. -1 .. 1 ]
if (isEqualElement list1to5 list5to1) then
    printfn "Lists %A and %A have at least one equal element at the same position." list1to5 list5to1
else
    printfn "Lists %A and %A do not have an equal element at the same position." list1to5 list5to1

Produkcja jest w następujący sposób:

Lists [1; 2; 3; 4; 5] and [5; 4; 3; 2; 1] have at least one equal element at the same position.

Można użyć List.forall chcesz sprawdzić, czy wszystkie elementy listy spełniają warunek.

let isAllZeroes list = List.forall (fun elem -> elem = 0.0) list
printfn "%b" (isAllZeroes [0.0; 0.0])
printfn "%b" (isAllZeroes [0.0; 1.0])

Produkcja jest w następujący sposób:

true
false

Podobnie List.forall2 Określa, czy wszystkie elementy w odpowiednich pozycjach na dwóch listach spełniają wyrażenia logicznego, który obejmuje każda para elementów.

let listEqual list1 list2 = List.forall2 (fun elem1 elem2 -> elem1 = elem2) list1 list2
printfn "%b" (listEqual [0; 1; 2] [0; 1; 2])
printfn "%b" (listEqual [0; 0; 0] [0; 1; 0])

Produkcja jest w następujący sposób:

true
false

Dd233224.collapse_all(pl-pl,VS.110).gifOperacje sortowania na listach

List.sort, List.sortBy, i List.sortWith funkcji sortowania list.Funkcja sortowania określa, który z tych trzech funkcji, aby użyć.List.sortużywa domyślnego porównania rodzajowe.Porównania rodzajowe używa globalnego operatorów na podstawie funkcji Porównaj rodzajowe do porównywania wartości.Działa efektywnie z szerokiego zakresu typów elementów, takich jak proste typy liczbowe, krotek, rekordy, związki dyskryminowanych, listy, tablice i dowolnego typu, który implementuje IComparable.Dla typów wdrożenie tego IComparable, używa porównania rodzajowe CompareTo funkcji.Porównania rodzajowe również działa z ciągami znaków, ale używa porządku sortowania niezależny od kultury.Porównania rodzajowe nie powinno służyć nieobsługiwanego typu, takich jak typy funkcji.Również wydajność porównania rodzajowe domyślny jest najlepszy dla małych typy strukturalnej; dla większych structured typów, które muszą być porównywane i często sortowane, należy rozważyć zaimplementowanie IComparable oraz zapewnienie skutecznego wdrażania CompareTo metody.

List.sortByPrzejście z funkcji, która zwraca wartość, która jest używana jako kryterium sortowania i List.sortWith przyjmuje porównanie funkcji jako argumentu.Te ostatnie dwie funkcje są przydatne podczas pracy z typami, który nie obsługuje porównania lub gdy porównanie wymaga bardziej złożonych semantykę porównania, jak w przypadku ciągów kultury aware.

Poniższy przykład ilustruje użycie List.sort.

let sortedList1 = List.sort [1; 4; 8; -2; 5]
printfn "%A" sortedList1

Produkcja jest w następujący sposób:

[-2; 1; 4; 5; 8]

Poniższy przykład ilustruje użycie List.sortBy.

let sortedList2 = List.sortBy (fun elem -> abs elem) [1; 4; 8; -2; 5]
printfn "%A" sortedList2

Produkcja jest w następujący sposób:

[1; -2; 4; 5; 8]

Następny przykład ilustruje użycie List.sortWith.W tym przykładzie funkcja niestandardowych porównanie compareWidgets jest używany do porównania najpierw jednego pola niestandardowego typu i gdy następnie innej wartości pierwszego pola są równe.

type Widget = { ID: int; Rev: int }

let compareWidgets widget1 widget2 =
   if widget1.ID < widget2.ID then -1 else
   if widget1.ID > widget2.ID then 1 else
   if widget1.Rev < widget2.Rev then -1 else
   if widget1.Rev > widget2.Rev then 1 else
   0

let listToCompare = [
    { ID = 92; Rev = 1 }
    { ID = 110; Rev = 1 }
    { ID = 100; Rev = 5 }
    { ID = 100; Rev = 2 }
    { ID = 92; Rev = 1 }
    ]

let sortedWidgetList = List.sortWith compareWidgets listToCompare
printfn "%A" sortedWidgetList

Produkcja jest w następujący sposób:

  [{ID = 92;
    Rev = 1;}; {ID = 92;
                Rev = 1;}; {ID = 100;
                            Rev = 2;}; {ID = 100;
                                        Rev = 5;}; {ID = 110;
                                                    Rev = 1;}]

Dd233224.collapse_all(pl-pl,VS.110).gifOperacje wyszukiwania na listach

Liczne operacje wyszukiwania są obsługiwane dla list.Najprostszy, List.find, umożliwia wyszukiwanie pierwszego elementu, który odpowiada określony warunek.

Poniższy przykład kodu ilustruje użycie List.find , aby znaleźć numer pierwszego, który jest podzielna przez 5 na liście.

let isDivisibleBy number elem = elem % number = 0
let result = List.find (isDivisibleBy 5) [ 1 .. 100 ]
printfn "%d " result

Wynik jest 5.

Jeśli elementy musi zostać przekształcona, po pierwsze, wywołanie List.pick, który stoi funkcji, że zwraca wartość opcji i szuka pierwszej opcji wartość, która jest Some(x).Zamiast zwracać elementu, List.pick zwraca wynik x.Jeśli nie znaleziono, List.pick wyrzuca KeyNotFoundException.Poniższy kod ilustruje wykorzystanie List.pick.

let valuesList = [ ("a", 1); ("b", 2); ("c", 3) ]

let resultPick = List.pick (fun elem ->
                    match elem with
                    | (value, 2) -> Some value
                    | _ -> None) valuesList
printfn "%A" resultPick

Produkcja jest w następujący sposób:

"b"

Inna grupa operacji wyszukiwania, List.tryFind i pokrewne funkcje zwracają wartość opcji.List.tryFind Funkcja zwraca pierwszy element listy, który spełnia warunek, jeśli istnieje taki element, ale wartość opcji None Jeśli nie.Zmiana List.tryFindIndex zwraca indeks elementu, jeśli nie zostanie znalezione, a nie samego elementu.Funkcje te są przedstawione w poniższym kodzie.

let list1d = [1; 3; 7; 9; 11; 13; 15; 19; 22; 29; 36]
let isEven x = x % 2 = 0
match List.tryFind isEven list1d with
| Some value -> printfn "The first even value is %d." value
| None -> printfn "There is no even value in the list."

match List.tryFindIndex isEven list1d with
| Some value -> printfn "The first even value is at position %d." value
| None -> printfn "There is no even value in the list."

Produkcja jest w następujący sposób:

The first even value is 22.
The first even value is at position 8.

Dd233224.collapse_all(pl-pl,VS.110).gifOperacje arytmetyczne na listach

Typowe operacje arytmetyczne, takie jak Suma i średnia są wbudowane w listy Moduł.Aby pracować z List.sum, typ elementu listy musi obsługiwać + operatora i ma wartość zero.Wszystkie wbudowane typy arytmetyczne spełnia te warunki.Aby pracować z List.average, typ elementu musi obsługiwać rejon bez reszty wyklucza integralną typów, ale pozwala na pływających typy punktów.List.sumBy i List.averageBy funkcje podjąć funkcji jako parametr, a wyniki tej funkcji są używane do obliczania wartości dla Suma lub średnia.

Poniższy kod demonstruje użycie List.sum, List.sumBy, i List.average.

// Compute the sum of the first 10 integers by using List.sum.
let sum1 = List.sum [1 .. 10]

// Compute the sum of the squares of the elements of a list by using List.sumBy.
let sum2 = List.sumBy (fun elem -> elem*elem) [1 .. 10]

// Compute the average of the elements of a list by using List.average.
let avg1 = List.average [0.0; 1.0; 1.0; 2.0]

printfn "%f" avg1

Dane wyjściowe są 1.000000.

Poniższy kod ilustruje wykorzystanie List.averageBy.

let avg2 = List.averageBy (fun elem -> float elem) [1 .. 10]
printfn "%f" avg2

Dane wyjściowe są 5.5.

Dd233224.collapse_all(pl-pl,VS.110).gifListy i krotek

Listy zawierające krotek mogą być manipulowane przez zip i Rozpakuj funkcji.Te funkcje łączenie dwóch list wartości pojedynczego w jedną listę krotek lub podzielić jedną listę krotek na dwie listy pojedynczych wartości.Najprostszym List.zip funkcja przyjmuje dwie listy pojedynczych elementów i produkuje jedną listę par krotki.Inna wersja List.zip3, przyjmuje trzy listy pojedynczych elementów i tworzy pojedynczy wykaz krotek, który ma trzy elementy.Poniższy przykład kodu ilustruje użycie List.zip.

let list1 = [ 1; 2; 3 ]
let list2 = [ -1; -2; -3 ]
let listZip = List.zip list1 list2
printfn "%A" listZip

Produkcja jest w następujący sposób:

[(1, -1); (2, -2); (3; -3)]

Poniższy przykład kodu ilustruje użycie List.zip3.

let list3 = [ 0; 0; 0]
let listZip3 = List.zip3 list1 list2 list3
printfn "%A" listZip3

Produkcja jest w następujący sposób:

[(1, -1, 0); (2, -2, 0); (3, -3, 0)]

Odpowiednie rozpakowane wersje, List.unzip i List.unzip3, podjąć list krotek oraz zwrotu list krotki, gdzie pierwsza lista zawiera wszystkie elementy, które zostały po raz pierwszy w każdej krotki, a drugi wykaz zawiera drugi element każdej krotki i tak dalej.

Poniższy przykład kodu ilustruje użycie List.unzip.

let lists = List.unzip [(1,2); (3,4)]
printfn "%A" lists
printfn "%A %A" (fst lists) (snd lists)

Produkcja jest w następujący sposób:

([1; 3], [2; 4])
[1; 3] [2; 4]

Poniższy przykład kodu ilustruje użycie List.unzip3.

let listsUnzip3 = List.unzip3 [(1,2,3); (4,5,6)]
printfn "%A" listsUnzip3

Produkcja jest w następujący sposób:

([1; 4], [2; 5], [3; 6])

Dd233224.collapse_all(pl-pl,VS.110).gifDziałających na elementy listy

F# obsługuje szereg operacji na elementach listy.Jest to najprostsza List.iter, który umożliwia wywoływanie funkcji na każdy element listy.Obejmują odmiany List.iter2, umożliwia wykonywanie operacji na elementach dwie listy List.iteri, która przypomina List.iter z wyjątkiem, że indeks każdy element jest przekazywana jako argument do funkcji, która jest wywoływana dla każdego elementu i List.iteri2, który jest kombinacją funkcji List.iter2 i List.iteri.Poniższy przykład kodu ilustruje te funkcje.

let list1 = [1; 2; 3]
let list2 = [4; 5; 6]
List.iter (fun x -> printfn "List.iter: element is %d" x) list1
List.iteri(fun i x -> printfn "List.iteri: element %d is %d" i x) list1
List.iter2 (fun x y -> printfn "List.iter2: elements are %d %d" x y) list1 list2
List.iteri2 (fun i x y ->
               printfn "List.iteri2: element %d of list1 is %d element %d of list2 is %d"
                 i x i y)
            list1 list2

Produkcja jest w następujący sposób:

List.iter: element is 1
List.iter: element is 2
List.iter: element is 3
List.iteri: element 0 is 1
List.iteri: element 1 is 2
List.iteri: element 2 is 3
List.iter2: elements are 1 4
List.iter2: elements are 2 5
List.iter2: elements are 3 6
List.iteri2: element 0 of list1 is 1; element 0 of list2 is 4
List.iteri2: element 1 of list1 is 2; element 1 of list2 is 5
List.iteri2: element 2 of list1 is 3; element 2 of list2 is 6

Innym często używanych funkcji, która przekształca elementy listy jest List.map, który umożliwia zastosowanie funkcji do każdego elementu listy i wszystkie wyniki do nowej listy.List.map2 i List.map3 są różnice, które wielu list.Można również użyć List.mapi i List.mapi2, jeśli obok elementu, funkcja musi zostać przekazany indeks każdego elementu.Jedyną różnicą między List.mapi2 i List.mapi jest to, że List.mapi2 działa z dwiema listami.Poniższy przykład ilustruje List.map.

let list1 = [1; 2; 3]
let newList = List.map (fun x -> x + 1) list1
printfn "%A" newList

Produkcja jest w następujący sposób:

[2; 3; 4]

Następujący przykład przedstawia wykorzystanie List.map2.

let list1 = [1; 2; 3]
let list2 = [4; 5; 6]
let sumList = List.map2 (fun x y -> x + y) list1 list2
printfn "%A" sumList

Produkcja jest w następujący sposób:

[5; 7; 9]

Następujący przykład przedstawia wykorzystanie List.map3.

let newList2 = List.map3 (fun x y z -> x + y + z) list1 list2 [2; 3; 4]
printfn "%A" newList2

Produkcja jest w następujący sposób:

[7; 10; 13]

Następujący przykład przedstawia wykorzystanie List.mapi.

let newListAddIndex = List.mapi (fun i x -> x + i) list1
printfn "%A" newListAddIndex

Produkcja jest w następujący sposób:

[1; 3; 5]

Następujący przykład przedstawia wykorzystanie List.mapi2.

let listAddTimesIndex = List.mapi2 (fun i x y -> (x + y) * i) list1 list2
printfn "%A" listAddTimesIndex

Produkcja jest w następujący sposób:

[0; 7; 18]

List.Collect przypomina List.map, z wyjątkiem, że każdy element tworzy listę i wykazy te są tak łączone do ostatecznego wykazu.W poniższym kodzie każdy element listy generuje trzy cyfry.Te wszystkie zbierane są w jedną listę.

let collectList = List.collect (fun x -> [for i in 1..3 -> x * i]) list1
printfn "%A" collectList

Produkcja jest w następujący sposób:

[1; 2; 3; 2; 4; 6; 3; 6; 9]

Można również użyć List.filter, która przyjmuje logiczną warunku i tworzy nową listę, która składa się tylko z elementów, które spełniają określony warunek.

let evenOnlyList = List.filter (fun x -> x % 2 = 0) [1; 2; 3; 4; 5; 6]

Lista wynikowy jest [2; 4; 6].

Połączenie mapy i filtra List.choose umożliwia Przekształć, a następnie zaznacz elementy, w tym samym czasie.List.choosestosuje się funkcję, która zwraca wartość opcji do każdego elementu listy i zwraca nową listę wyników dla elementów, gdy funkcja zwraca wartość opcji Some.

Poniższy kod demonstruje użycie List.choose Aby wybrać słów pisanych wielkimi literami, z listy słów.

let listWords = [ "and"; "Rome"; "Bob"; "apple"; "zebra" ]
let isCapitalized (string1:string) = System.Char.IsUpper string1.[0]
let results = List.choose (fun elem ->
    match elem with
    | elem when isCapitalized elem -> Some(elem + "'s")
    | _ -> None) listWords
printfn "%A" results

Produkcja jest w następujący sposób:

["Rome's"; "Bob's"]

Dd233224.collapse_all(pl-pl,VS.110).gifDziałających na wiele list

Listy mogą być połączone razem.Aby łączenie dwóch list w jeden, użyj List.append.Aby dołączyć więcej niż dwie listy, użyj List.concat.

let list1to10 = List.append [1; 2; 3] [4; 5; 6; 7; 8; 9; 10]
let listResult = List.concat [ [1; 2; 3]; [4; 5; 6]; [7; 8; 9] ]
List.iter (fun elem -> printf "%d " elem) list1to10
printfn ""
List.iter (fun elem -> printf "%d " elem) listResult

Dd233224.collapse_all(pl-pl,VS.110).gifSkładanie i operacji skanowania

Niektóre operacje listy obejmują współzależności między wszystkie elementy listy.Operacje składanie i skanowania są jak List.iter i List.map tym, że wywołania funkcji dla każdego elementu, ale operacje te zapewniają dodatkowy parametr o nazwie akumulator który przenosi informacje, za pomocą obliczeń.

Użyj List.fold do wykonywania obliczeń na liście.

Poniższy przykład kodu ilustruje użycie List.fold do wykonywania różnych operacji.

Wykaz jest przesunięta; akumulator acc jest wartością, która jest przekazywana wzdłuż w trakcie wykonywania obliczeń.Pierwszy argument ma akumulator i elementu listy i zwraca tymczasowe wynik obliczeń dla tego elementu listy.Drugi argument jest akumulator o wartości początkowej.

let sumList list = List.fold (fun acc elem -> acc + elem) 0 list
printfn "Sum of the elements of list %A is %d." [ 1 .. 3 ] (sumList [ 1 .. 3 ])

// The following example computes the average of a list.
let averageList list = (List.fold (fun acc elem -> acc + float elem) 0.0 list / float list.Length)

// The following example computes the standard deviation of a list.
// The standard deviation is computed by taking the square root of the
// sum of the variances, which are the differences between each value
// and the average.
let stdDevList list =
    let avg = averageList list
    sqrt (List.fold (fun acc elem -> acc + (float elem - avg) ** 2.0 ) 0.0 list / float list.Length)

let testList listTest =
    printfn "List %A average: %f stddev: %f" listTest (averageList listTest) (stdDevList listTest)

testList [1; 1; 1]
testList [1; 2; 1]
testList [1; 2; 3]

// List.fold is the same as to List.iter when the accumulator is not used.
let printList list = List.fold (fun acc elem -> printfn "%A" elem) () list
printList [0.0; 1.0; 2.5; 5.1 ]

// The following example uses List.fold to reverse a list.
// The accumulator starts out as the empty list, and the function uses the cons operator
// to add each successive element to the head of the accumulator list, resulting in a
// reversed form of the list.
let reverseList list = List.fold (fun acc elem -> elem::acc) [] list
printfn "%A" (reverseList [1 .. 10])

Wersje te funkcje, które mają cyfry w nazwie funkcji działają na więcej niż jednej liście.Na przykład List.fold2 wykonuje obliczenia na dwie listy.

Poniższy przykład ilustruje użycie List.fold2.

// Use List.fold2 to perform computations over two lists (of equal size) at the same time.
// Example: Sum the greater element at each list position.
let sumGreatest list1 list2 = List.fold2 (fun acc elem1 elem2 ->
                                              acc + max elem1 elem2) 0 list1 list2

let sum = sumGreatest [1; 2; 3] [3; 2; 1]
printfn "The sum of the greater of each pair of elements in the two lists is %d." sum

List.foldi List.scan różnią się w tym List.fold zwraca wartość końcowego dodatkowy parametr, ale List.scan zwraca listę wartości pośrednie (wraz z końcowej) dodatkowy parametr.

Odwrotne zmienności, każda z tych funkcji zawiera na przykład, List.foldBack, który różni się w kolejności, w których listy jest przesunięta i kolejność argumentów.Ponadto List.fold i List.foldBack mają zmian, List.fold2 i List.foldBack2, które wymagają dwóch list o równej długości.Funkcję, która wykonuje na każdy element można użyć do wykonania niektórych akcji odpowiednie elementy z obu list.Typy elementów dwóch list mogą być różne, jak w poniższym przykładzie, w którym jedna lista zawiera kwoty transakcji dla konta bankowego, i inne listy zawiera typ transakcji: depozytu lub wycofania.

// Discriminated union type that encodes the transaction type.
type Transaction =
    | Deposit
    | Withdrawal

let transactionTypes = [Deposit; Deposit; Withdrawal]
let transactionAmounts = [100.00; 1000.00; 95.00 ]
let initialBalance = 200.00

// Use fold2 to perform a calculation on the list to update the account balance.
let endingBalance = List.fold2 (fun acc elem1 elem2 ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2)
                                initialBalance
                                transactionTypes
                                transactionAmounts
printfn "%f" endingBalance

Dla obliczenia, takie jak sumowanie List.fold i List.foldBack mają ten sam efekt, ponieważ wynik zależy od kolejności na przechodzenie.W poniższym przykładzie List.foldBack jest używana do dodawania elementów na liście.

let sumListBack list = List.foldBack (fun acc elem -> acc + elem) list 0
printfn "%d" (sumListBack [1; 2; 3])

// For a calculation in which the order of traversal is important, fold and foldBack have different
// results. For example, replacing fold with foldBack in the listReverse function
// produces a function that copies the list, rather than reversing it.
let copyList list = List.foldBack (fun elem acc -> elem::acc) list []
printfn "%A" (copyList [1 .. 10])

Poniższy przykład zwraca się na przykład konto bankowe.Ten czas jest dodawany nowy typ transakcji: Obliczanie odsetek.Saldo końcowe teraz zależy od celu transakcji.

type Transaction2 =
    | Deposit
    | Withdrawal
    | Interest

let transactionTypes2 = [Deposit; Deposit; Withdrawal; Interest]
let transactionAmounts2 = [100.00; 1000.00; 95.00; 0.05 / 12.0 ]
let initialBalance2 = 200.00

// Because fold2 processes the lists by starting at the head element,
// the interest is calculated last, on the balance of 1205.00.
let endingBalance2 = List.fold2 (fun acc elem1 elem2 ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2
                                | Interest -> acc * (1.0 + elem2))
                                initialBalance2
                                transactionTypes2
                                transactionAmounts2
printfn "%f" endingBalance2
// Because foldBack2 processes the lists by starting at end of the list,
// the interest is calculated first, on the balance of only 200.00.
let endingBalance3 = List.foldBack2 (fun elem1 elem2 acc ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2
                                | Interest -> acc * (1.0 + elem2))
                                transactionTypes2
                                transactionAmounts2
                                initialBalance2
printfn "%f" endingBalance3

Funkcja List.reduce jest nieco podobny do List.fold i List.scan, z wyjątkiem, że zamiast przekazywanie wokół oddzielnych akumulator, List.reduce ma funkcję, która ma dwa argumenty elementu wpisz zamiast tylko jednego i jeden z tych argumentów działa jako akumulator, co oznacza, przechowuje pośredni wynik obliczeń.List.reducerozpoczyna się od działających na pierwszym elementy listy dwóch, a następnie używa wynik operacji wraz z następnego elementu.Ponieważ nie jest oddzielnym akumulator, który ma swój własny typ List.reduce może być używane zamiast List.fold tylko gdy akumulator i typ elementu mają tego samego typu.Poniższy kod demonstruje użycie List.reduce.List.reduceJeśli nie ma żadnych elementów listy, pod warunkiem, zgłasza wyjątek.

W poniższym kodzie pierwsze wywołanie w celu wyrażenia lambda jest podane argumenty 2 i 4 i zwraca 6 i następne wywołanie podano argumentów, 6 i 10, więc wynik jest równy 16.

let sumAList list =
    try
        List.reduce (fun acc elem -> acc + elem) list
    with
       | :? System.ArgumentException as exc -> 0

let resultSum = sumAList [2; 4; 10]
printfn "%d " resultSum

Dd233224.collapse_all(pl-pl,VS.110).gifKonwersja między listy i inne typy kolekcji

List Moduł zawiera funkcje do konwersji i zarówno sekwencji i tablic.Aby przekonwertować do lub z sekwencji, użyj List.toSeq lub List.ofSeq.Aby przekonwertować do lub z tablicy, należy użyć List.toArray lub List.ofArray.

Dd233224.collapse_all(pl-pl,VS.110).gifDodatkowe operacje

Aby uzyskać informacje o dodatkowych operacji na listach, zobacz temat informacje biblioteki Moduł Collections.list (F#).

Zobacz też

Informacje

Sekwencje (F#)

Opcje (F#)

Inne zasoby

F# Language Reference

F# typów

Tablice (F#)