Tablice (F#)
Tablice są stałym rozmiarze, zero-oparte tych zbiorów danych kolejnych elementów, których wszystkie są tego samego typu.
Tworzenie tablic
Można utworzyć tablic na kilka sposobów.Można utworzyć tablicy małych przez wyświetlanie kolejnych wartości między [| i |] i oddzielone średnikami, jak pokazano w poniższych przykładach.
let array1 = [| 1; 2; 3 |]
Każdy element można również umieścić w osobnym wierszu, w którym jest opcjonalne w przypadku separator średnika.
let array1 =
[|
1
2
3
|]
Typ elementów tablicy wywnioskować na podstawie literały, używane i muszą być zgodne.Poniższy kod powoduje błąd, ponieważ 1.0 jest pływaka, a 2 i 3 są liczbami całkowitymi.
// Causes an error.
// let array2 = [| 1.0; 2; 3 |]
Umożliwia także sekwencji wyrażeń utworzyć tablic.Oto przykład, w którym tworzony jest obiekt array kwadratów liczb całkowitych od 1 do 10.
let array3 = [| for i in 1 .. 10 -> i * i |]
Aby utworzyć array, w którym wszystkie elementy są inicjowane na wartość zero, należy użyć Array.zeroCreate.
let arrayOfTenZeroes : int array = Array.zeroCreate 10
Dostęp do elementów
Elementy tablicy można uzyskać dostęp za pomocą kropki operator (.) i nawiasy kwadratowe ([i]).
array1.[0]
Indeksy tablicy rozpoczynają się od 0.
Można również uzyskać dostęp elementów tablicy przy użyciu notacji plasterek umożliwia określenie Podzakres tablicy.Przykłady notacji plasterka.
// Accesses elements from 0 to 2.
array1.[0..2]
// Accesses elements from the beginning of the array to 2.
array1.[..2]
// Accesses elements from 2 to the end of the array.
array1.[2..]
W przypadku notacji plasterek utworzono nową kopię tablicy.
Typy tablic i moduły
Jest typu F# wszystkie tablice.NET Framework typu Array.W związku z tym, tablice F# obsługuje wszystkie funkcje dostępne w Array.
bibliotekamodułMicrosoft.FSharp.Collections.Array obsługuje operacje na tablice jednowymiarowe. Moduły Array2D, Array3D, i Array4D zawiera funkcje, które są obsługiwane operacje na tablicach dwa, trzy i cztery wymiary, odpowiednio.Można utworzyć tablic rangi większej niż cztery za pomocą Array.
Proste funkcje
Array.Get pobiera element.Array.length daje długości tablicy.Array.set ustawia element do określonej wartości.Poniższy przykład kodu ilustruje użycie tych funkcji.
let array1 = Array.create 10 ""
for i in 0 .. array1.Length - 1 do
Array.set array1 i (i.ToString())
for i in 0 .. array1.Length - 1 do
printf "%s " (Array.get array1 i)
Wprowadza dane wyjściowe.
0 1 2 3 4 5 6 7 8 9
Funkcje, które tworzą tablic
Kilka funkcji utworzyć tablic bez konieczności istniejącej macierzy.Array.Empty tworzy nową tablicę, która nie zawiera żadnych elementów.Tablica.utworzyć utworzy tablicę o określonym rozmiarze i ustawia wszystkie elementy do podanej wartości.Array.init tworzy tablicę, biorąc pod uwagę wymiaru i funkcja do wygenerowania elementy.Array.zeroCreate tworzy tablicę, w którym wszystkie elementy są inicjowane na wartość zero dla tablicy typu.Poniższy kod ilustruje te funkcje.
let myEmptyArray = Array.empty
printfn "Length of empty array: %d" myEmptyArray.Length
printfn "Array of floats set to 5.0: %A" (Array.create 10 5.0)
printfn "Array of squares: %A" (Array.init 10 (fun index -> index * index))
let (myZeroArray : float array) = Array.zeroCreate 10
Wprowadza dane wyjściowe.
Length of empty array: 0
Area of floats set to 5.0: [|5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0|]
Array of squares: [|0; 1; 4; 9; 16; 25; 36; 49; 64; 81|]
Migracji tworzy nową tablicę, który zawiera elementy, które są kopiowane z istniejącej tablicy.Należy zauważyć, że kopia jest kopii płytkiej, co oznacza, jeśli typ referencyjnytyp elementu, tylko odwołanie jest kopiowany, nie obiektźródłowego.Poniższy przykład kodu ilustruje to.
open System.Text
let firstArray : StringBuilder array = Array.init 3 (fun index -> new StringBuilder(""))
let secondArray = Array.copy firstArray
// Reset an element of the first array to a new value.
firstArray.[0] <- new StringBuilder("Test1")
// Change an element of the first array.
firstArray.[1].Insert(0, "Test2") |> ignore
printfn "%A" firstArray
printfn "%A" secondArray
Dane wyjściowe poprzedniego kodu jest w następujący sposób:
[|Test1; Test2; |]
[|; Test2; |]
Ciąg Test1 pojawia się tylko w pierwszym tablicy, ponieważ operacja tworzenia nowego elementu powoduje zastąpienie odniesienia w firstArray , ale nie wpływa na oryginalny odniesienie do pusty ciąg, który jest nadal obecny w secondArray.Ciąg Test2 pojawia się w obu tablicach, ponieważ Insert operacji na StringBuilder typu wpływa na podstawową StringBuilder obiekt, który jest wywoływany w obu tablicach.
Array.Sub generuje nową tablicę z Podzakres tablicy.Podzakres można określić, podając indeks początkowy i długość.Poniższy kod demonstruje użycie Array.sub.
let a1 = [| 0 .. 99 |]
let a2 = Array.sub a1 5 10
printfn "%A" a2
Dane wyjściowe pokazuje, że subarray rozpoczyna się od elementu 5 i zawiera elementy 10.
[|5; 6; 7; 8; 9; 10; 11; 12; 13; 14|]
Tablica.dołączyć tworzy nową tablicę, łącząc dwie tablice istniejących.
Poniższy kod demonstruje, Array.append.
printfn "%A" (Array.append [| 1; 2; 3|] [| 4; 5; 6|])
Dane wyjściowe poprzedniego kodu jest następująca:
[|1; 2; 3; 4; 5; 6|]
Array.Choose powoduje zaznaczenie elementów tablicy, aby uwzględnić w nowej tablicy.Poniższy kod demonstruje, Array.choose.Należy zauważyć, że typ elementu w tablicy nie pasuje do typu wartości zwracane w polu Typ opcji.W tym przykładzie jest typ elementu int i opcji jest wynikiem wielomianowej funkcja elem*elem - 1, jako liczba liczba zmiennoprzecinkowa .
printfn "%A" (Array.choose (fun elem -> if elem % 2 = 0 then
Some(float (elem*elem - 1))
else
None) [| 1 .. 10 |])
Dane wyjściowe poprzedniego kodu jest następująca:
[|3.0; 15.0; 35.0; 63.0; 99.0|]
Array.Collect uruchamia funkcja na każdy element tablicy istniejącej macierzy, a następnie zbiera elementy wygenerowane przez funkcja i łączy je do nowej tablicy.Poniższy kod demonstruje, Array.collect.
printfn "%A" (Array.collect (fun elem -> [| 0 .. elem |]) [| 1; 5; 10|])
Dane wyjściowe poprzedniego kodu jest następująca:
[|0; 1; 0; 1; 2; 3; 4; 5; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10|]
Array.concat trwa sekwencji tablic i łączy je w pojedynczej tablicy.Poniższy kod demonstruje, Array.concat.
let multiplicationTable max = seq { for i in 1 .. max -> [| for j in 1 .. max -> (i, j, i*j) |] }
printfn "%A" (Array.concat (multiplicationTable 3))
Dane wyjściowe poprzedniego kodu jest następująca:
[|(1, 1, 1); (1, 2, 2); (1, 3, 3); (2, 1, 2); (2, 2, 4); (2, 3, 6); (3, 1, 3);
(3, 2, 6); (3, 3, 9)|]
Array.Filter trwa logiczny warunku funkcja i generuje nowej tablicy, który zawiera tylko elementy z tablicy wejściowego, dla którego warunek jest spełniony.Poniższy kod demonstruje, Array.filter.
printfn "%A" (Array.filter (fun elem -> elem % 2 = 0) [| 1 .. 10|])
Dane wyjściowe poprzedniego kodu jest następująca:
[|2; 4; 6; 8; 10|]
Array.Rev generuje nową tablicę przez odwracanie kolejności istniejącej macierzy.Poniższy kod demonstruje, Array.rev.
let stringReverse (s: string) =
System.String(Array.rev (s.ToCharArray()))
printfn "%A" (stringReverse("!dlrow olleH"))
Dane wyjściowe poprzedniego kodu jest następująca:
"Hello world!"
Można łatwo połączyć funkcje w tablicy moduł przekształcających tablice za pomocą operator potoku (| >), jak pokazano w poniższym przykładzie.
[| 1 .. 10 |]
|> Array.filter (fun elem -> elem % 2 = 0)
|> Array.choose (fun elem -> if (elem <> 8) then Some(elem*elem) else None)
|> Array.rev
|> printfn "%A"
Dane wyjściowe
[|100; 36; 16; 4|]
Tablice wielowymiarowe
Tablica wielowymiarowa mogą być tworzone, ale nie jest brak składni do pisania Tablica wielowymiarowa literału.Użyj operatorarray2D , aby utworzyć tablicę z sekwencji sekwencji elementów tablicy. Sekwencje mogą być literałów array lub listy.Na przykład poniższy kod tworzy dwuwymiarowej tablicy.
let my2DArray = array2D [ [ 1; 0]; [0; 1] ]
Można również użyć funkcjaArray2D.init zainicjować tablic w dwóch wymiarach i podobnych dla tablic trzy lub cztery wymiary dostępne są funkcje. Te funkcje podjąć funkcja , która jest używana do utworzyć elementów.Aby utworzyć dwuwymiarowej tablicy, który zawiera elementy, ustaw wartość początkową zamiast określania funkcja, należy użyć Array2D.utworzyćfunkcja, która jest również dostępna dla tablic maksymalnie cztery wymiary. Poniższy przykład kodu najpierw pokazuje, jak utworzyć tablicę tablic które zawierają żądane elementy, a następnie używa Array2D.init do generowania pożądanych dwuwymiarowej tablicy.
let arrayOfArrays = [| [| 1.0; 0.0 |]; [|0.0; 1.0 |] |]
let twoDimensionalArray = Array2D.init 2 2 (fun i j -> arrayOfArrays.[i].[j])
Tablica indeksowania i krojenie składnia jest obsługiwana dla tablic do rangi 4.Po określeniu indeks w wielu wymiarów umożliwia przecinkami oddzielne wskaźników, jak pokazano w poniższym przykładzie kodu.
twoDimensionalArray.[0, 1] <- 1.0
Typ dwuwymiarowej tablicy jest zapisywany jako <type>[,] (na przykład, int[,], double[,]), i rodzaju tablicą trójwymiarową jest zapisywany jako <type>[,,], i tak dalej dla tablic wyższych wymiarów.
Tylko podzbiór funkcji dostępnych dla tablice jednowymiarowe jest również dostępna dla tablic wielowymiarowych.For more information, see Moduł Collections.Array (F#), Moduł Collections.Array2D (F#), Moduł Collections.Array3D (F#), and Moduł Collections.Array4D (F#).
logiczny Funkcje tablic
Funkcje Array.exists i Array.exists2 test elementy w jednym lub dwóch tablic, odpowiednio.Te funkcje podjąć badania funkcja i powrócić true , jeśli istnieje element (lub parę elementu dla Array.exists2) który spełnia warunek.
Poniższy kod demonstruje użycie Array.exists i Array.exists2.W tych przykładach nowe funkcje są tworzone poprzez stosowanie tylko jednego z argumentów, w tych przypadkach funkcja argument.
let allNegative = Array.exists (fun elem -> abs (elem) = elem) >> not
printfn "%A" (allNegative [| -1; -2; -3 |])
printfn "%A" (allNegative [| -10; -1; 5 |])
printfn "%A" (allNegative [| 0 |])
let haveEqualElement = Array.exists2 (fun elem1 elem2 -> elem1 = elem2)
printfn "%A" (haveEqualElement [| 1; 2; 3 |] [| 3; 2; 1|])
Dane wyjściowe poprzedniego kodu jest następująca:
true
false
false
true
Podobnie, funkcjaArray.forall testów tablicy, aby ustalić, czy każdy element spełnia warunek logiczny . Zmiana Array.forall2 działa tak samo za pomocą logicznyfunkcja , która obejmuje elementy dwóch tablic o równej długości. Poniższy kod ilustruje użycie tych funkcji.
let allPositive = Array.forall (fun elem -> elem > 0)
printfn "%A" (allPositive [| 0; 1; 2; 3 |])
printfn "%A" (allPositive [| 1; 2; 3 |])
let allEqual = Array.forall2 (fun elem1 elem2 -> elem1 = elem2)
printfn "%A" (allEqual [| 1; 2 |] [| 1; 2 |])
printfn "%A" (allEqual [| 1; 2 |] [| 2; 1 |])
Dane wyjściowe tych przykładów jest następująca:
false
true
true
false
Tablice wyszukiwania
Array.Find przyjmuje logicznyfunkcja i zwraca pierwszy element, dla którego funkcja zwraca true, lub nie wnosi KeyNotFoundException Jeśli zostanie znaleziony żaden element, który spełnia warunek. Array.findIndex przypomina Array.find, z wyjątkiem, że zwraca ona indeksu elementu, a nie samego elementu.
Następujący kod dodaje do zastosowań Array.find i Array.findIndex aby zlokalizować numer, który jest idealny kwadrat i doskonałe modułu.
let arrayA = [| 2 .. 100 |]
let delta = 1.0e-10
let isPerfectSquare (x:int) =
let y = sqrt (float x)
abs(y - round y) < delta
let isPerfectCube (x:int) =
let y = System.Math.Pow(float x, 1.0/3.0)
abs(y - round y) < delta
let element = Array.find (fun elem -> isPerfectSquare elem && isPerfectCube elem) arrayA
let index = Array.findIndex (fun elem -> isPerfectSquare elem && isPerfectCube elem) arrayA
printfn "The first element that is both a square and a cube is %d and its index is %d." element index
Wprowadza dane wyjściowe.
The first element that is both a square and a cube is 64 and its index is 62.
Array.tryFind przypomina Array.find, z wyjątkiem, że jego wynik jest typu opcji, a następnie zwraca None , jeśli element nie zostanie znaleziony.Array.tryFindpowinny być używane zamiast Array.find gdy nie wiadomo czy pasujący element w tablicy.Podobnie Array.tryFindIndex przypomina Array.findIndex z wyjątkiem, że typ opcji jest zwracana wartość.Jeśli element nie zostanie znaleziony, opcja ta jest None.
Poniższy kod demonstruje użycie Array.tryFind.Kod ten zależy od poprzedniego kodu.
let delta = 1.0e-10
let isPerfectSquare (x:int) =
let y = sqrt (float x)
abs(y - round y) < delta
let isPerfectCube (x:int) =
let y = System.Math.Pow(float x, 1.0/3.0)
abs(y - round y) < delta
let lookForCubeAndSquare array1 =
let result = Array.tryFind (fun elem -> isPerfectSquare elem && isPerfectCube elem) array1
match result with
| Some x -> printfn "Found an element: %d" x
| None -> printfn "Failed to find a matching element."
lookForCubeAndSquare [| 1 .. 10 |]
lookForCubeAndSquare [| 100 .. 1000 |]
lookForCubeAndSquare [| 2 .. 50 |]
Wprowadza dane wyjściowe.
Found an element: 1
Found an element: 729
Użyj Array.tryPick gdy zachodzi potrzeba Przekształć element dodatkowo do znalezienia go.Wynik jest pierwszy element, dla którego funkcja zwraca element przekształconych jako wartość opcji lub None , jeśli element nie zostanie znaleziony.
Poniższy kod ilustruje wykorzystanie Array.tryPick.W takim przypadku zamiast wyrażenia lambda, kilka funkcji lokalne pomocnik są definiowane w celu uproszczenia kodu.
let findPerfectSquareAndCube array1 =
let delta = 1.0e-10
let isPerfectSquare (x:int) =
let y = sqrt (float x)
abs(y - round y) < delta
let isPerfectCube (x:int) =
let y = System.Math.Pow(float x, 1.0/3.0)
abs(y - round y) < delta
// intFunction : (float -> float) -> int -> int
// Allows the use of a floating point function with integers.
let intFunction function1 number = int (round (function1 (float number)))
let cubeRoot x = System.Math.Pow(x, 1.0/3.0)
// testElement: int -> (int * int * int) option
// Test an element to see whether it is a perfect square and a perfect
// cube, and, if so, return the element, square root, and cube root
// as an option value. Otherwise, return None.
let testElement elem =
if isPerfectSquare elem && isPerfectCube elem then
Some(elem, intFunction sqrt elem, intFunction cubeRoot elem)
else None
match Array.tryPick testElement array1 with
| Some (n, sqrt, cuberoot) -> printfn "Found an element %d with square root %d and cube root %d." n sqrt cuberoot
| None -> printfn "Did not find an element that is both a perfect square and a perfect cube."
findPerfectSquareAndCube [| 1 .. 10 |]
findPerfectSquareAndCube [| 2 .. 100 |]
findPerfectSquareAndCube [| 100 .. 1000 |]
findPerfectSquareAndCube [| 1000 .. 10000 |]
findPerfectSquareAndCube [| 2 .. 50 |]
Wprowadza dane wyjściowe.
Found an element 1 with square root 1 and cube root 1.
Found an element 64 with square root 8 and cube root 4.
Found an element 729 with square root 27 and cube root 9.
Found an element 4096 with square root 64 and cube root 16.
Wykonywanie obliczeń dotyczących tablic
Array.averagefunkcja zwraca średnią każdego elementu w tablicy. Jest ograniczony do typów elementów, które obsługują dokładny podział przez liczba całkowita, która zawiera typy liczba zmiennoprzecinkowa , ale nie integralną typów.Array.averageByfunkcja zwraca wartość średnią z wyników wywołania funkcja dla każdego elementu. Tablica typu integralną, można użyć Array.averageBy i mieć funkcjakonwertować każdy element typu liczba zmiennoprzecinkowa , do obliczeń.
Użyj Array.max lub Array.min Aby uzyskać elementu maksymalnej lub minimalnej, jeśli typ elementu obsługuje tę funkcję.Podobnie Array.maxBy i Array.minBy umożliwia funkcja mają być wykonane po pierwsze, przypuszczalnie w celu przekształcenia do typu, który obsługuje porównania.
Array.sum dodaje elementy tablicy, a Array.sumBy wywołuje funkcja dla każdego elementu i dodaje wyniki razem.
Aby wykonać funkcja każdego elementu w tablicy bez przechowywania wartości zwracanej, należy użyć Array.iter.funkcja udziałem dwóch tablic o równej długości, użyj Array.iter2.Należy również zachować tablicy wyników funkcja, użyć mapa lub Array.map2, która działa na dwóch tablic w czasie.
Różnice Array.iteri i Array.iteri2 Zezwalaj na indeks elementu uczestniczyć w kursach; to samo dotyczy dla Array.mapi i Array.mapi2.
Funkcje Array.fold, Array.foldBack, Array.reduce, Array.reduceBack, Array.scan, i Array.scanBackwykonać algorytmów, które obejmują wszystkie elementy tablicy. Podobnie, odmiany Array.fold2 i Array.foldBack2 wykonać obliczenia w dwóch tablicach.
Te funkcje do wykonywania obliczeń odpowiadają funkcji o tej samej nazwie w z listy moduł.Przykłady użycia, zobacz List (F#).
Modyfikowanie tablic
Array.set ustawia element do określonej wartości.Array.Fill ustawia zakres elementów w tablicy do określonej wartości.Poniższy kod zawiera przykład Array.fill.
let arrayFill1 = [| 1 .. 25 |]
Array.fill arrayFill1 2 20 0
printfn "%A" arrayFill1
Wprowadza dane wyjściowe.
[|1; 2; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 23; 24; 25|]
Można użyć Array.blit do kopiowania podsekcji jednej tablicy do innego tablicy.
Konwertowanie do i z innych typów
Array.ofList tworzy tablicę z listy.Array.ofSeq tworzy tablicę z sekwencji.Array.toList i Array.toSeqkonwertować na inne typy kolekcji z typu tablicy.
Sortowanie tablic
Użyj Array.sort Aby posortować obiekt array za pomocą porównania rodzajowe funkcja.Użyj Array.sortBy określić generuje wartość funkcja , o których mowa w klucz, aby posortować za pomocą porównania rodzajowe funkcja w kluczu.Użyj Array.sortWith , jeśli użytkownik chce dostarczać niestandardowe porównanie funkcja.Array.sort, Array.sortBy, i Array.sortWith wszystkie zwraca posortowaną tablicę jako nowej tablicy.Różnice Array.sortInPlace, Array.sortInPlaceBy, i Array.sortInPlaceWith modyfikowania istniejącej tablicy zamiast zwracać nową.
Tablice i krotek
Funkcje Array.zip i rozpakowaćtablicekonwertować par krotka do krotek tablic i vice versa. Array.zip3 i Array.unzip3 są podobne, z wyjątkiem, że pracują ze krotek trzech elementów lub krotek trzy tablic.
Obliczenia równoległe w tablicach
modułArray.Parallel zawiera funkcje do wykonywania obliczeń równoległych na tablicach. Ten moduł nie jest dostępne w aplikacji przeznaczonych dla wersji.NET Framework przed do wersji 4