Udostępnij za pośrednictwem


Listy (F#)

Na liście w F # jest uporządkowaną, niezmienna szereg elementów tego samego typu.Aby wykonać podstawowe operacje na listach, należy użyć funkcji w modułu listy.

Tworzenie i Inicjowanie listy

Listę można zdefiniować, wpisując jawnie układ elementów oddzielonych średnikami i ujęte w nawiasy kwadratowe, jak pokazano w następującym wierszu kodu.

let list123 = [ 1; 2; 3 ]

Można również umieścić podziałów między elementami, w tym przypadku średniki są opcjonalne.Ostatnie składni może spowodować czytelność kodu podczas wyrażeń inicjowania elementu są dłuższe lub chcesz dołączyć komentarz dla każdego elementu.

let list123 = [
    1
    2
    3 ]

Zazwyczaj wszystkie elementy listy muszą być tego samego typu.Wystąpił wyjątek jest uzyskiwany typów w listę, w jakiej elementy są określane jako typ bazowy może mieć elementy o wartościach.W związku z tym następujących jest akceptowany, ponieważ oba Button i CheckBox pochodzić od klasy Control.

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

Można również zdefiniować elementy listy przy użyciu zakres wskazywany przez liczb całkowitych rozdzielonych operatora zakresu (..), jak pokazano w następującym kodzie.

let list1 = [ 1 .. 10 ]

Można również definiować listę przy użyciu pętli konstrukcji, tak jak następujący kod.

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

Pusta lista jest określona przez parę nawiasy kwadratowe niczego nie między nimi.

// An empty list. 
let listEmpty = []

Wyrażenie sekwencji można także użyć do tworzenia listy.Znajdują się w temacie "Sekwencję wyrażeń" sekwencji.Na przykład następujący kod tworzy listę kwadratów liczb całkowitych od 1 do 10.

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

Operatory do pracy z listy

Elementy można dołączyć do listy za pomocą :: operator (wad).Jeśli list1 jest [2; 3; 4], następujący kod tworzy list2 jako [100; 2; 3; 4].

let list2 = 100 :: list1

Można połączyć listy, które mają niezgodne typy przy użyciu @ operatora, tak jak następujący kod.Jeśli list1 jest [2; 3; 4] i list2 jest [100; 2; 3; 4 ], ten kod tworzy list3 jako [2; 3; 4; 100; 2; 3; 4].

let list3 = list1 @ list2

Dostępne są funkcje do wykonywania operacji na listach modułu listy.

Ponieważ listy w F # są niezmienna, wszystkie operacje modyfikowania wygenerować nowe listy zamiast modyfikowania istniejących list.

Wyświetla w F # są wykonywane jako pojedynczo połączonej listy, co oznacza, że operacje, które uzyskują dostęp do tylko nagłówek listy są O(1), i dostęp do elementu jest O (n).

Właściwości

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

Właściwość

Typ

Opis

HEAD

'T

Pierwszy element.

Pusty

'T list

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

IsEmpty

bool

trueJeśli na liście nie ma żadnych elementów.

Element

'T

Element pod określonym indeksem (liczony od zera).

Długość

int

Liczba elementów.

Zakończenie

'T list

Lista bez pierwszym elementem.

Oto kilka przykładów przy użyciu 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))

Przy użyciu listy

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ą istotne do programowania funkcjonalności.

Rekursję z listy

Listy są dostosowane do cyklicznego techniki programowania.Należy rozważyć operacji, które należy wykonać dla każdego elementu listy.Możesz zrobić to rekursywnie, działające na nagłówek listy, a następnie przekazywanie końcowego fragmentu na liście, który znajduje się lista mniejszy składający się z pierwotnej listy bez pierwszym elementem, z powrotem na kolejny poziom rekursji.

Można zapisać funkcji cykliczne, możesz użyć operatora wadach (::) w dopasowywanie do wzorców, co umożliwia Rozdziel nagłówek listy z końcowego fragmentu.

Poniższy przykładowy kod przedstawia sposób użycia dopasowywanie do wzorców do zaimplementowania cyklicznego funkcję, 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 sprawdza się w małych list, ale dla większych list można przepełnienie stosu.Poniższy kod zwiększa na ten kod przy użyciu argumentu akumulatora, standardowa metoda do pracy z funkcjami cyklicznego.Użyj argumentu akumulatora sprawia, że cyklicznego zakończenie funkcję, która zapisuje miejsca 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 to funkcja cyklicznego pobierającej dwie listy.Pierwsza lista zawiera cyfry, którego wielokrotności zostaną usunięte, a druga lista znajduje się lista, z którego chcesz usunąć liczby.Kod w poniższym przykładzie funkcja ta cyklicznego do wyeliminowania wszystkich innych niż liczby pierwsze z listy, pozostawiając listę liczby pierwsze 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)

Dane wyjściowe są 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

Modułu listy zawiera funkcje, które uzyskują dostęp do elementów listy.Head element to najszybszy i najłatwiejszy dostępu.Użyj właściwości Head lub funkcja modułu List.head.Zakończenie listy może uzyskać dostęp za pomocą Krańc właściwości lub List.tail funkcji.Aby znaleźć element według indeksu, należy użyć List.nth funkcji.List.nthPrzechodzi i listy.Dlatego jest 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 tablic jest O(1).

Logiczna operacji na listach

List.isEmpty funkcji określa, czy lista ma żadnych elementów.

List.exists funkcja ma zastosowanie wartość logiczną testu na elementy listy i zwraca true Jeśli dowolny element spełnia testu.List.exists2 jest podobny, ale działa na pary kolejnych elementów w dwóch list.

Poniższy kod przedstawia 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)

Dane wyjściowe są w następujący sposób:

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

Poniższy przykład pokazuje korzystanie z 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

Dane wyjściowe są 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 Jeśli chcesz sprawdzić, czy warunek spełnia wszystkie elementy z listy.

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])

Dane wyjściowe są w następujący sposób:

true
false

Podobnie List.forall2 Określa, czy wszystkie elementy w odpowiedniej pozycji w dwóch list spełniają mające związek z każdej pary elementów wyrażenie logiczne.

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])

Dane wyjściowe są w następujący sposób:

true
false

Operacje sortowania na listach

List.sort, List.sortBy, i List.sortWith funkcje sortować listy.Funkcja sortowania określa, które z tych trzech funkcji do użycia.List.sortużywa domyślnym porównaniem ogólny.Porównanie ogólnego używa operatorów globalnych na podstawie porównania ogólnego funkcji do porównywania wartości.Działa efektywnie z różnych typów elementów, takich jak liczbowych typów prostych, spójne kolekcje, rekordy, związków rozłącznej, list, tablic i dowolnego typu, który implementuje IComparable.Dla typów które implementują IComparable, używa ogólnego porównanie CompareTo funkcji.Porównanie ogólnego również działa z ciągów, ale używa kolejność sortowania niezależnie od kultury.Ogólny porównanie nie powinien być używany wraz nieobsługiwanych typów, takich jak typy funkcji.Ponadto wydajność domyślnym porównaniem ogólny jest najlepsze dla małych strukturalnego typów; dla większych strukturalnego typów, które muszą być porównana i często sortowane, należy rozważyć zaimplementowanie IComparable i zapewniając implementację wydajne CompareTo metody.

List.sortBywykonuje funkcję, która zwraca wartość, która jest używana jako kryterium sortowania i List.sortWith przyjmuje jako argument funkcji porównania.Te ostatnie dwie funkcje są przydatne podczas pracy z typami, które nie obsługują porównywania lub podczas porównywania wymaga bardziej złożonych semantyki porównanie, tak jak w przypadku ciągów obsługujący kultury.

Poniższy przykład pokazuje korzystanie z List.sort.

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

Dane wyjściowe są w następujący sposób:

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

Poniższy przykład pokazuje korzystanie z List.sortBy.

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

Dane wyjściowe są w następujący sposób:

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

W następnym przykładzie pokazano korzystanie z List.sortWith.W tym przykładzie funkcji niestandardowych porównanie compareWidgets służy do porównywania najpierw jedno pole Typ niestandardowy, a następnie innego when wartości pierwszego pola są takie same.

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

Dane wyjściowe są 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;}]

Operacji wyszukiwania na listach

Wiele operacji wyszukiwania są obsługiwane w przypadku list.Najprostszy, List.find, umożliwia znalezienie pierwszy element, który odpowiada określony warunek.

Poniższy przykładowy kod przedstawia użycie List.find można znaleźć pierwszą liczbę, która 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 to 5.

Jeśli elementy muszą zostać przekształcone najpierw, należy wywołać List.pick, który wykonuje funkcję który zwraca opcją i szuka pierwszą opcję wartość, która jest Some(x).Zamiast zwracać elementu, List.pick zwraca wynik w x.Jeśli nie zostanie znaleziony, List.pick zgłasza wyjątek KeyNotFoundException.Poniższy kod prezentuje sposób użycia 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

Dane wyjściowe są w następujący sposób:

"b"

Inną grupę operacji wyszukiwania, List.tryFind i powiązane, zwracają wartość opcji.List.tryFind Funkcja zwraca pierwszy element na liście, która spełnia warunek, jeśli taki element istnieje, ale wartość opcji None w przeciwnym razie.Zmiana List.tryFindIndex zwraca indeks elementu, jeśli nie zostanie znalezione, a nie samego elementu.Te funkcje są przedstawione w następujący kod.

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."

Dane wyjściowe są w następujący sposób:

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

Operacje arytmetyczne na listach

Wspólne operacje arytmetyczne, takie jak Suma i średnia zawierają wbudowane modułu listy.Aby pracować z List.sum, typ elementu listy musi obsługiwać + operatora i ma wartość zero.Wszystkie wbudowane typy arytmetycznych spełnia te warunki.Aby pracować z List.average, typ elementu musi obsługiwać dzielenie bez reszty, który wyklucza typy zintegrowane, ale pozwala na przestawne typy punktów.List.sumBy i List.averageBy funkcje pobierać funkcji jako parametr, a wyniki tej funkcji są używane do obliczania wartości dla sumy lub średniej.

Poniższy kod przedstawia 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

Wynik to 1.000000.

Poniższy kod prezentuje sposób użycia List.averageBy.

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

Wynik to 5.5.

Wyświetla i spójne kolekcje

Listy zawierające spójne kolekcje można manipulować zip i rozpakowanie funkcji.Te funkcje połączyć dwie listy pojedynczych wartości w jednej listy spójne kolekcje lub podzielić jedną listą spójnych kolekcji na dwie listy pojedynczej wartości.Najprostsze List.zip funkcja pobiera dwie listy pojedynczych elementów i tworzy pojedynczy Lista par spójnej kolekcji.Inna wersja List.zip3, ma trzy listy pojedynczych elementów i tworzy listę pojedynczy spójnych kolekcji, która ma trzy elementy.Poniższy przykładowy kod przedstawia użycie List.zip.

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

Dane wyjściowe są w następujący sposób:

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

Poniższy przykładowy kod przedstawia użycie List.zip3.

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

Dane wyjściowe są w następujący sposób:

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

Odpowiednie rozpakowanie wersje, List.unzip i List.unzip3, wykorzystanie list spójnych kolekcji i wyświetla zwrotny w spójnej kolekcji, gdzie pierwsza lista zawiera wszystkie elementy, które zostały po raz pierwszy w każdej spójnej kolekcji, a drugą listę drugi element każdego spójnej kolekcji, itd.

Poniższy przykładowy kod przedstawia użycie List.unzip.

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

Dane wyjściowe są w następujący sposób:

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

Poniższy przykładowy kod przedstawia użycie List.unzip3.

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

Dane wyjściowe są w następujący sposób:

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

Na liście elementów

Język F # obsługuje wiele różnych operacji na liście elementów.Jest to najprostszy List.iter, co umożliwia wywoływania funkcji dla każdego elementu listy.Obejmują wersje List.iter2, który służy do wykonywania operacji na elementy listy, List.iteri, która jest podobna List.iter z tą różnicą, że indeks każdego elementu jest przekazywany jako argument funkcji, które jest wywoływane dla każdego elementu i List.iteri2, która to połączenie funkcji List.iter2 i List.iteri.Poniższy przykładowy kod przedstawia tych funkcji.

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

Dane wyjściowe są 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

Inna funkcja często używanych przekształca elementy listy jest List.map, dzięki czemu można zastosować funkcji do każdego elementu listy i wszystkie wyniki do nowej listy.List.map2 i List.map3 są rozpoznawane wykorzystujących wiele list.Można również użyć List.mapi i List.mapi2, jeśli oprócz elementu, funkcja musi być przekazany indeks każdego elementu.Jedyną różnicą między List.mapi2 i List.mapi jest List.mapi2 działa z listy.Poniższy przykład przedstawia List.map.

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

Dane wyjściowe są w następujący sposób:

[2; 3; 4]

W poniższym przykładzie przedstawiono użycie 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

Dane wyjściowe są w następujący sposób:

[5; 7; 9]

W poniższym przykładzie przedstawiono użycie List.map3.

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

Dane wyjściowe są w następujący sposób:

[7; 10; 13]

W poniższym przykładzie przedstawiono użycie List.mapi.

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

Dane wyjściowe są w następujący sposób:

[1; 3; 5]

W poniższym przykładzie przedstawiono użycie List.mapi2.

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

Dane wyjściowe są w następujący sposób:

[0; 7; 18]

List.Collect jest jak List.map, z tą różnicą, że każdy element tworzy listę i te listy są połączone na końcowym listę.Poniższy kod każdy element listy generuje trzy liczby.Te są wszystkie zebrane w jednej listy.

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

Dane wyjściowe są 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 zawiera tylko elementy, które spełniają danego warunku.

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

Wynikowa lista jest [2; 4; 6].

Połączenie mapy i filtru List.choose umożliwia transform i wybierz elementy w tym samym czasie.List.choosestosuje funkcję, która zwraca opcję do każdego elementu listy i zwraca nową listę elementów wyniki, jeśli funkcja zwraca wartość opcji Some.

Poniższy kod przedstawia użycie List.choose do wybierania wielkimi literami wyrazów poza listę 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

Dane wyjściowe są w następujący sposób:

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

Działające na wiele list

Wyświetla można łączyć ze sobą.Aby przyłączyć się do jednego dwie listy, należy użyć List.append.Aby dołączyć więcej niż dwóch list, należy użyć 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

Składanie i operacji skanowania

Niektóre operacje listy obejmują zależnościami między wszystkie elementy listy.Operacje złożenia i skanowania przypominają List.iter i List.map w tym wywołania funkcji dla każdego elementu, ale te operacje zapewnić dodatkowy parametr o nazwie akumulatora który ma informacje o za pośrednictwem obliczaną.

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

Poniższy przykładowy kod przedstawia użycie List.fold do wykonywania różnych operacji.

Lista jest przesunięta; akumulatora acc jest wartość, która została przekazana wzdłuż w trakcie wykonywania obliczeń.Pierwszy argument akumulatora i element listy i zwraca wynik tymczasowy obliczeń dla tego elementu listy.Drugi argument jest wartością początkową akumulatora.

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 liście więcej niż jeden.Na przykład List.fold2 wykonuje obliczenia na dwie listy.

Poniższy przykład pokazuje korzystanie z 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 ostateczna wartość parametru dodatkowe, ale List.scan zwraca listę wartości pośrednich (wraz z końcowej) dodatkowy parametr.

Każda z tych funkcji obejmuje odwrotnej zmiany, na przykład List.foldBack, który różni się w kolejności, w którego lista jest przesunięta i kolejność argumentów.Ponadto List.fold i List.foldBack ma zmian, List.fold2 i List.foldBack2, które wymagają dwie listy równej długości.Funkcję, która wykonuje na każdym elemencie umożliwia wykonywanie akcji odpowiednie elementy obu list.Typy elementu dwie listy mogą być różne, jak w poniższym przykładzie, w której jedna lista zawiera kwoty transakcji dla konta bank, a inne lista 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

Do obliczeń, takich jak podsumowania List.fold i List.foldBack mieć taki sam efekt, ponieważ wynik nie zależy od kolejności przechodzenia.W poniższym przykładzie List.foldBack jest używane 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 na przykład konta bank.Ten czas jest dodawany nowy typ transakcji: Obliczanie odsetek.Saldo końcowe teraz zależy od kolejności 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, takich jak List.fold i List.scan, z tą różnicą, że zamiast pozytywny wokół oddzielne akumulatora, List.reduce wykonuje funkcję, która wymaga dwóch argumentów elementu wpisz zamiast co najmniej jeden, a jeden z tych argumentów działa jako akumulatora, co oznacza przechowuje pośredni wyniku obliczeń.List.reducerozpoczyna się od działających w przypadku pierwszego elementów listy dwóch, a następnie używa wynik operacji wraz z następnego elementu.Ponieważ nie jest osobnym akumulatora, która ma własny typ List.reduce można użyć zamiast właściwości List.fold tylko gdy akumulatora i typ elementu mieć tego samego typu.Poniższy kod przedstawia użycie List.reduce.List.reducezgłasza wyjątek, jeśli nie ma żadnych elementów listy.

Poniższy kod pierwszym wywołaniu do wyrażenia lambda jest podawana argumenty 2 do 4, a następnie zwraca 6 i kolejnego połączenia jest podawana argumenty 6 i 10, więc wynik jest 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

Konwertowanie listy i inne typy kolekcji

List Modułu udostępnia funkcje służące do konwertowania do i z sekwencji i tablic.Aby dokonać konwersji do lub z sekwencji, użyj List.toSeq lub List.ofSeq.Aby dokonać konwersji do lub z tablicy, użyj List.toArray lub List.ofArray.

Dodatkowe czynności

Informacje o dodatkowych operacji na listach, na ten temat można znaleźć w temacie Odwołanie do biblioteki Collections.List — Moduł (F#).

Zobacz też

Informacje

Sekwencje (F#)

Opcje (F#)

Inne zasoby

Materiały referencyjne dotyczące języka F#

Typy F#

Tablice (F#)