F # - listy
W języku F # lista jest uporządkowaną, niezmienną serią elementów tego samego typu. Jest to do pewnego stopnia równoważne strukturze danych z połączonej listy.
Moduł F #, Microsoft.FSharp.Collections.List,ma wspólne operacje na listach. Jednak F # importuje ten moduł automatycznie i udostępnia go każdej aplikacji F #.
Tworzenie i inicjowanie listy
Poniżej przedstawiono różne sposoby tworzenia list -
Korzystanie z listy literals.
Za pomocą cons (: :) operator.
Używając List.init metoda modułu List.
Korzystanie z niektórych syntactic constructs nazywa List Comprehensions.
Lista literałów
W tej metodzie wystarczy określić rozdzieloną średnikami sekwencję wartości w nawiasach kwadratowych. Na przykład -
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
Wady (: :) Operator
Za pomocą tej metody można dodać niektóre wartości, poprzedzając lub cons-ingdo istniejącej listy przy użyciu operatora ::. Na przykład -
let list2 = 1::2::3::4::5::6::7::8::9::10::[];;
[] oznacza pustą listę.
Lista metody inicjalizacji
Metoda List.init modułu List jest często używana do tworzenia list. Ta metoda ma typ -
val init : int -> (int -> 'T) -> 'T list
Pierwszy argument to żądana długość nowej listy, a drugi argument to funkcja inicjująca, która generuje pozycje na liście.
Na przykład,
let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))
Tutaj funkcja indeksu generuje listę.
Lista ujęć
Listy składane to specjalne konstrukcje składniowe używane do generowania list.
Składnia składni listy F # występuje w dwóch formach - zakresów i generatorów.
Zakresy mają konstrukcje - [start .. end] i [start .. step .. end]
Na przykład,
let list3 = [1 .. 10]
Generatory mają konstrukcję - [for x in collection do ... yield expr]
Na przykład,
let list6 = [ for a in 1 .. 10 do yield (a * a) ]
Ponieważ yield słowo kluczowe wypycha pojedynczą wartość na listę, słowo kluczowe, yield!, umieszcza zbiór wartości na liście.
Poniższa funkcja demonstruje powyższe metody -
Przykład
(* using list literals *)
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
(*using cons operator *)
let list2 = 1 :: 2 :: 3 :: []
printfn "The list: %A" list2
(* using range constructs*)
let list3 = [1 .. 10]
printfn "The list: %A" list3
(* using range constructs *)
let list4 = ['a' .. 'm']
printfn "The list: %A" list4
(* using init method *)
let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))
printfn "The list: %A" list5
(* using yield operator *)
let list6 = [ for a in 1 .. 10 do yield (a * a) ]
printfn "The list: %A" list6
(* using yield operator *)
let list7 = [ for a in 1 .. 100 do if a % 3 = 0 && a % 5 = 0 then yield a]
printfn "The list: %A" list7
(* using yield! operator *)
let list8 = [for a in 1 .. 3 do yield! [ a .. a + 3 ] ]
printfn "The list: %A" list8
Kiedy kompilujesz i wykonujesz program, daje to następujące dane wyjściowe -
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: [1; 2; 3]
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: ['a'; 'b'; 'c'; 'd'; 'e'; 'f'; 'g'; 'h'; 'i'; 'j'; 'k'; 'l'; 'm']
The list: [(0, 0, 0); (1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64)]
The list: [1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
The list: [15; 30; 45; 60; 75; 90]
The list: [1; 2; 3; 4; 2; 3; 4; 5; 3; 4; 5; 6]
Właściwości typu danych listy
W poniższej tabeli przedstawiono różne właściwości typu danych listy -
własność | Rodzaj | Opis |
---|---|---|
Głowa | „T | Pierwszy element. |
Pusty | Lista 'T | Właściwość statyczna, która zwraca pustą listę odpowiedniego typu. |
Jest pusty | bool | true jeśli lista nie zawiera elementów. |
Pozycja | „T | Element o określonym indeksie (liczony od zera). |
Długość | int | Liczba elementów. |
Ogon | Lista 'T | Lista bez pierwszego elementu. |
Poniższy przykład pokazuje użycie tych właściwości -
Przykład
let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
// Use of 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))
Kiedy kompilujesz i wykonujesz program, daje to następujące dane wyjściowe -
list1.IsEmpty is false
list1.Length is 8
list1.Head is 2
list1.Tail.Head is 4
list1.Tail.Tail.Head is 6
list1.Item(1) is 4
Podstawowe operatory na liście
Poniższa tabela przedstawia podstawowe operacje na typie danych listy -
Wartość | Opis |
---|---|
dołącz: 'Lista T →' Lista T → 'Lista T. | Zwraca nową listę zawierającą elementy pierwszej listy, po których następują elementy drugiej. |
średnia: 'T lista → ^ T | Zwraca średnią elementów na liście. |
średnia Przez: ('T → ^ U) →' T lista → ^ U | Zwraca średnią z elementów wygenerowanych przez zastosowanie funkcji do każdego elementu listy. |
wybierz: (opcja 'T →' U) → 'Lista T →' Lista U | Stosuje daną funkcję do każdego elementu listy. Zwraca listę zawierającą wyniki dla każdego elementu, z którego funkcja zwracaSome. |
zbierać: ('T →' Lista U) → 'Lista T →' Lista U | Do każdego elementu listy stosuje daną funkcję. Łączy wszystkie wyniki i zwraca połączoną listę. |
concat: seq <'T lista> →' T lista | Zwraca nową listę, która zawiera elementy każdej z list w kolejności. |
puste: 'T lista | Zwraca pustą listę podanego typu. |
istnieje: ('T → bool) →' T lista → bool | Sprawdza, czy którykolwiek element listy spełnia podany predykat. |
istnieje2: ('T1 →' T2 → bool) → 'Lista T1 →' Lista T2 → bool | Sprawdza, czy jakakolwiek para odpowiednich elementów list spełnia podany predykat. |
filtr: ('T → bool) →' T lista → 'T lista | Zwraca nową kolekcję zawierającą tylko elementy kolekcji, dla których zwraca dany predykat true. |
znajdź: ('T → bool) →' Lista T → 'T | Zwraca pierwszy element, dla którego zwraca dana funkcja true. |
findIndex: ('T → bool) →' T lista → int | Zwraca indeks pierwszego elementu na liście, który spełnia podany predykat. |
fold: ('Stan →' T → 'Stan) →' Stan → 'Lista T →' Stan | Stosuje funkcję do każdego elementu kolekcji, tworząc wątek argumentu akumulatora przez obliczenia. Ta funkcja przyjmuje drugi argument i stosuje do niego funkcję oraz pierwszy element listy. Następnie przekazuje ten wynik do funkcji wraz z drugim elementem i tak dalej. Na koniec zwraca wynik końcowy. Jeśli funkcją wejściową jest f, a elementy to i0 ... iN, to ta funkcja oblicza f (... (fs i0) i1 ...) iN. |
fold2: ('Stan →' T1 → 'T2 →' Stan) → 'Stan →' Lista T1 → 'Lista T2 →' Stan | Stosuje funkcję do odpowiednich elementów dwóch kolekcji, tworząc wątek argumentu akumulatora przez obliczenia. Kolekcje muszą mieć identyczne rozmiary. Jeśli funkcją wejściową jest f, a elementy to i0 ... iN oraz j0 ... jN, to ta funkcja oblicza f (... (fs i0 j0) ...) iN jN. |
foldBack: ('T →' Stan → 'Stan) →' Lista T → 'Stan →' Stan | Stosuje funkcję do każdego elementu kolekcji, tworząc wątek argumentu akumulatora przez obliczenia. Jeśli funkcja wejściowa isf, a elementy to i0 ... iN, oblicza f i0 (... (f iN s)). |
foldBack2: ('T1 →' T2 → 'Stan →' Stan) → 'Lista T1 →' Lista T2 → 'Stan →' Stan | Stosuje funkcję do odpowiednich elementów dwóch kolekcji, tworząc wątek argumentu akumulatora przez obliczenia. Kolekcje muszą mieć identyczne rozmiary. Jeśli funkcją wejściową jest f, a elementy to i0 ... iN oraz j0 ... jN, to ta funkcja oblicza f i0 j0 (... (f iN jN s)). |
forall: ('T → bool) →' T lista → bool | Sprawdza, czy wszystkie elementy kolekcji spełniają podany predykat. |
forall2: ('T1 →' T2 → bool) → 'Lista T1 →' Lista T2 → bool | Sprawdza, czy wszystkie odpowiadające elementy kolekcji spełniają podany predykat parami. |
head: 'T lista →' T | Zwraca pierwszy element listy. |
init: int → (int → 'T) →' T list | Tworzy listę poprzez wywołanie danego generatora w każdym indeksie. |
isEmpty: 'T lista → bool | Zwroty true jeśli lista nie zawiera elementów, false Inaczej. |
iter: ('T → jednostka) →' Lista T → jednostka | Stosuje daną funkcję do każdego elementu kolekcji. |
iter2: ('T1 →' T2 → jednostka) → 'Lista T1 →' Lista T2 → jednostka | Stosuje daną funkcję do dwóch kolekcji jednocześnie. Kolekcje muszą mieć identyczny rozmiar. |
iteri: (int → 'T → jednostka) →' Lista T → jednostka | Stosuje daną funkcję do każdego elementu kolekcji. Liczba całkowita przekazana do funkcji wskazuje indeks elementu. |
iteri2: (int → 'T1 →' T2 → jednostka) → 'Lista T1 →' Lista T2 → jednostka | Stosuje daną funkcję do dwóch kolekcji jednocześnie. Kolekcje muszą mieć identyczny rozmiar. Liczba całkowita przekazana do funkcji wskazuje indeks elementu. |
długość: 'T lista → wew | Zwraca długość listy. |
mapa: ('T →' U) → 'Lista T →' Lista U | Tworzy nową kolekcję, której elementy są wynikiem zastosowania danej funkcji do każdego z elementów kolekcji. |
mapa2: ('T1 →' T2 → 'U) →' Lista T1 → 'Lista T2 →' Lista U | Tworzy nową kolekcję, której elementy są wynikiem zastosowania danej funkcji do odpowiednich elementów dwóch kolekcji parami. |
map3: ('T1 →' T2 → 'T3 →' U) → 'Lista T1 →' Lista T2 → 'Lista T3 →' Lista U | Tworzy nową kolekcję, której elementy są wynikiem zastosowania danej funkcji do odpowiednich elementów trzech kolekcji jednocześnie. |
mapi: (int → 'T →' U) → 'Lista T →' Lista U | Tworzy nową kolekcję, której elementy są wynikiem zastosowania danej funkcji do każdego z elementów kolekcji. Indeks w postaci liczby całkowitej przekazany do funkcji wskazuje indeks (od 0) transformowanego elementu. |
mapi2: (int → 'T1 →' T2 → 'U) →' Lista T1 → 'Lista T2 →' Lista U | Podobnie jak List.mapi, ale mapuje odpowiednie elementy z dwóch list o równej długości. |
max: 'T lista →' T | Zwraca największy ze wszystkich elementów listy w porównaniu przy użyciu Operators.max. |
maxBy: ('T →' U) → 'Lista T →' T | Zwraca największy ze wszystkich elementów listy w porównaniu przy użyciu metody Operators.max w wyniku funkcji. |
min: 'T lista →' T | Zwraca najniższy ze wszystkich elementów listy w porównaniu przy użyciu Operators.min. |
min Przez: ('T →' U) → 'Lista T →' T | Zwraca najniższy ze wszystkich elementów listy w porównaniu przy użyciu Operators.min w wyniku funkcji |
nth: 'T lista → int →' T | Indeksy do listy. Pierwszy element ma indeks 0. |
ofArray: 'T [] →' T lista | Tworzy listę z podanej tablicy. |
ofSeq: seq <'T> →' T list | Tworzy nową listę z podanego wyliczalnego obiektu. |
partycja: ('T → bool) →' T lista * 'T lista | Dzieli kolekcję na dwie kolekcje zawierające elementy, dla których zwraca dany predykat true i false odpowiednio. |
permute: (int → int) → 'T lista →' T lista | Zwraca listę ze wszystkimi elementami permutowanymi zgodnie z określoną permutacją. |
wybierz: (opcja 'T →' U) → 'Lista T →' U | Stosuje daną funkcję do kolejnych elementów, zwracając pierwszy wynik, gdy funkcja zwraca Some za jakąś wartość. |
zmniejsz: ('T →' T → 'T) →' Lista T → 'T | Stosuje funkcję do każdego elementu kolekcji, tworząc wątek argumentu akumulatora przez obliczenia. Ta funkcja stosuje określoną funkcję do pierwszych dwóch elementów listy. Następnie przekazuje ten wynik do funkcji wraz z trzecim elementem i tak dalej. Na koniec zwraca wynik końcowy. Jeśli funkcją wejściową jest f, a elementy są i0 ... iN, to funkcja ta oblicza f (... (f i0 i1) i2 ...) iN. |
redukcjaBack: ('T →' T → 'T) →' Lista T → 'T | Stosuje funkcję do każdego elementu kolekcji, tworząc wątek argumentu akumulatora przez obliczenia. Jeśli funkcja wejściowa isf, a elementy to i0 ... iN, to funkcja ta oblicza f i0 (... (f iN-1 iN)). |
replicate: (int → 'T →' T list) | Tworzy listę poprzez wywołanie danego generatora w każdym indeksie. |
rev: 'Lista T →' Lista T. | Zwraca nową listę z elementami w odwrotnej kolejności. |
skanowanie: ('Stan →' T → 'Stan) →' Stan → 'Lista T →' Lista stanów | Stosuje funkcję do każdego elementu kolekcji, tworząc wątek argumentu akumulatora przez obliczenia. Ta funkcja przyjmuje drugi argument i stosuje do niego określoną funkcję oraz pierwszy element listy. Następnie przekazuje ten wynik do funkcji wraz z drugim elementem i tak dalej. Na koniec zwraca listę wyników pośrednich i wyniku końcowego. |
scanBack: ('T →' Stan → 'Stan) →' Lista T → 'Stan →' Lista stanów | Podobnie jak foldBack, ale zwraca wyniki pośrednie i końcowe |
sortuj: 'T lista →' T lista | Sortuje podaną listę za pomocą Operators.compare. |
sortBy: ('T →' Key) → 'T list →' T list | Sortuje podaną listę za pomocą kluczy podanych przez daną projekcję. Klucze są porównywane za pomocą Operators.compare. |
sortWith: ('T →' T → int) → 'T lista →' T lista | Sortuje podaną listę przy użyciu podanej funkcji porównania. |
suma: ^ T lista → ^ T | Zwraca sumę elementów na liście. |
sumBy: ('T → ^ U) →' T lista → ^ U | Zwraca sumę wyników wygenerowanych przez zastosowanie funkcji do każdego elementu listy. |
ogon: 'Lista T →' Lista T. | Zwraca listę wejściową bez pierwszego elementu. |
toArray: 'T lista →' T [] | Tworzy tablicę z podanej listy. |
toSeq: 'T list → seq <' T> | Wyświetla podaną listę jako sekwencję. |
tryFind: ('T → bool) →' Lista T → opcja 'T | Zwraca pierwszy element, dla którego zwraca dana funkcja true. PowrótNone jeśli taki element nie istnieje. |
tryFindIndex: ('T → bool) →' T lista → opcja int | Zwraca indeks pierwszego elementu na liście, który spełnia podany predykat. PowrótNone jeśli taki element nie istnieje. |
tryPick: (opcja 'T →' U) → 'Lista T → opcja' U | Stosuje daną funkcję do kolejnych elementów, zwracając pierwszy wynik, gdy funkcja zwraca Someza jakąś wartość. Jeśli taki element nie istnieje, powróćNone. |
rozpakuj: ('T1 *' T2) lista → 'T1 lista *' Lista T2 | Dzieli listę par na dwie listy. |
unzip3: ('T1 *' T2 * 'T3) lista →' Lista T1 * 'Lista T2 *' Lista T3 | Dzieli listę trójek na trzy listy. |
zip: 'Lista T1 →' Lista T2 → ('T1 *' T2) lista | Łączy dwie listy w listę par. Obie listy muszą mieć równe długości. |
zip3: 'Lista T1 →' Lista T2 → 'Lista T3 → (' T1 * 'T2 *' T3) lista | Łączy trzy listy w listę trójek. Listy muszą mieć równe długości. |
Poniższe przykłady pokazują zastosowania powyższych funkcji -
Przykład 1
Ten program pokazuje rekurencyjne odwracanie listy -
let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
let reverse lt =
let rec loop acc = function
| [] -> acc
| hd :: tl -> loop (hd :: acc) tl
loop [] lt
printfn "The reversed list: %A" (reverse list1)
Kiedy kompilujesz i wykonujesz program, daje to następujące dane wyjściowe -
The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]
Możesz jednak użyć rev funkcja modułu w tym samym celu -
let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
printfn "The reversed list: %A" (List.rev list1)
Kiedy kompilujesz i wykonujesz program, daje to następujące dane wyjściowe -
The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]
Przykład 2
Ten program pokazuje filtrowanie listy przy użyciu rozszerzenia List.filter metoda -
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.filter (fun x -> x % 2 = 0);;
printfn "The Filtered list: %A" list2
Kiedy kompilujesz i wykonujesz program, daje to następujące dane wyjściowe -
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Filtered list: [2; 4; 6; 8; 10]
Przykład 3
Plik List.map metoda mapuje listę z jednego typu na inny -
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.map (fun x -> (x * x).ToString());;
printfn "The Mapped list: %A" list2
Kiedy kompilujesz i wykonujesz program, daje to następujące dane wyjściowe -
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Mapped list: ["1"; "4"; "9"; "16"; "25"; "36"; "49"; "64"; "81"; "100"]
Przykład 4
Plik List.append metoda, a operator @ dołącza jedną listę do drugiej -
let list1 = [1; 2; 3; 4; 5 ]
let list2 = [6; 7; 8; 9; 10]
let list3 = List.append list1 list2
printfn "The first list: %A" list1
printfn "The second list: %A" list2
printfn "The appened list: %A" list3
let lt1 = ['a'; 'b';'c' ]
let lt2 = ['e'; 'f';'g' ]
let lt3 = lt1 @ lt2
printfn "The first list: %A" lt1
printfn "The second list: %A" lt2
printfn "The appened list: %A" lt3
Kiedy kompilujesz i wykonujesz program, daje to następujące dane wyjściowe -
The first list: [1; 2; 3; 4; 5]
The second list: [6; 7; 8; 9; 10]
The appened list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The first list: ['a'; 'b'; 'c']
The second list: ['e'; 'f'; 'g']
The appened list: ['a'; 'b'; 'c'; 'e'; 'f'; 'g']
Przykład 5
Plik List.sortmetoda sortuje listę. PlikList.sum zwraca sumę elementów na liście i List.average metoda podaje średnią elementów na liście -
let list1 = [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
printfn "The list: %A" list1
let list2 = List.sort list1
printfn "The sorted list: %A" list2
let s = List.sum list1
let avg = List.average list1
printfn "The sum: %f" s
printfn "The average: %f" avg
Kiedy kompilujesz i wykonujesz program, daje to następujące dane wyjściowe -
The list: [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
The sorted list: [-10.0; -4.5; 0.0; 2.0; 8.0; 9.0; 11.2]
The sum: 15.700000
The average: 2.242857
Operacja „zwijania” stosuje funkcję do każdego elementu na liście, agreguje wynik funkcji w zmiennej akumulatorowej i zwraca akumulator jako wynik operacji zwinięcia.
Przykład 6
Plik List.fold metoda stosuje funkcję do każdego elementu od lewej do prawej, podczas gdy List.foldBack stosuje funkcję do każdego elementu od prawej do lewej.
let sumList list = List.fold (fun acc elem -> acc + elem) 0 list
printfn "Sum of the elements of list %A is %d." [ 1 .. 10 ] (sumList [ 1 .. 10 ])
Kiedy kompilujesz i wykonujesz program, daje to następujące dane wyjściowe -
Sum of the elements of list [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] is 55.