Matrizes (F#)
As matrizes são de tamanho fixo, zero-com base em coleções mutáveis de elementos de dados consecutivos que são todos do mesmo tipo.
Criação de matrizes
Você pode criar arrays de várias maneiras.Você pode criar uma matriz de pequena listando valores consecutivos entre [| e |] e separados por ponto e vírgula, como mostrado nos exemplos a seguir.
let array1 = [| 1; 2; 3 |]
Você também pode colocar cada elemento em uma separada linha, em que maiúsculas e minúsculas o ponto e vírgula separador é opcional.
let array1 =
[|
1
2
3
|]
O tipo de elementos de matriz é inferido dos literais usados e deve ser consistente.O código a seguir faz com que um erro porque 1.0 é uma float e 2 e 3 são números inteiros.
// Causes an error.
// let array2 = [| 1.0; 2; 3 |]
Você também pode usar expressões de sequência para criar matrizes.Veja a seguir um exemplo que cria uma matriz dos quadrados dos números inteiros de 1 a 10.
let array3 = [| for i in 1 .. 10 -> i * i |]
Para criar um array em que todos os elementos são inicializados para zero, use Array.zeroCreate.
let arrayOfTenZeroes : int array = Array.zeroCreate 10
Acessando Elementos
Você pode acessar os elementos de matriz, usando um ponto operador (.) e colchetes ([e]).
array1.[0]
Índices da matriz começam com 0.
Você também pode acessar os elementos da matriz usando a notação de fatia, o que permite que você especifique um Sub-intervalo da matriz.Seguem exemplos de notação de fatia.
// 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..]
Quando é usada a notação de fatia, é criada uma nova cópia da matriz.
Módulos e tipos de matriz
O tipo de todas as matrizes de F# é o.NET Framework equivalente Array.Portanto, F# arrays oferecem suporte a toda a funcionalidade disponível em Array.
Omódulode bibliotecaMicrosoft.FSharp.Collections.Array oferece suporte a operações em matrizes unidimensionais. Os módulos de Array2D, Array3D, e Array4D contêm funções que oferecem suporte a operações em matrizes de dois, três e quatro dimensões, respectivamente.Você pode criar matrizes de classificar superior a quatro por meio de Array.
Funções simples
Array.Get obtém de um elemento.Length retorna o comprimento de uma matriz.Set define um elemento com um valor especificado.O exemplo de código a seguir ilustra o uso dessas funções.
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)
A saída é da seguinte maneira.
0 1 2 3 4 5 6 7 8 9
Funções que criar matrizes
Várias funções criar arrays sem a necessidade de um array existente.Array.Empty cria uma nova matriz que não contém quaisquer elementos.Matriz.criar cria uma matriz de um tamanho especificado e define todos os elementos para os valores fornecidos.Array.Init cria uma matriz, dada uma dimensão e uma função para gerar os elementos.Array.zeroCreate cria uma matriz em que todos os elementos são inicializados para o valor de zero para o tipo da matriz.O código a seguir demonstra a essas funções.
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
A saída é da seguinte maneira.
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|]
Obter cria uma nova matriz que contém elementos que são copiados de um array existente.Observe que a cópia é uma cópia superficial, o que significa que, se o tipo de elemento é um tipo de referência, somente a referência é copiada, não o subjacente objeto.O exemplo de código a seguir ilustra isso.
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
A saída do código anterior é o seguinte:
[|Test1; Test2; |]
[|; Test2; |]
A seqüência de caracteres Test1 aparece apenas na primeira matriz porque a operação de criação de um novo elemento substitui a referência na firstArray mas não afeta a referência original para uma seqüência vazia que ainda está presente no secondArray.A seqüência de caracteres Test2 aparece nas duas matrizes, porque o Insert operação na StringBuilder afeta o tipo base StringBuilder objeto, que é citado nas duas matrizes.
Array.sub gera uma nova matriz a partir de uma sub-intervalo de uma matriz.Você pode especificar o Sub-intervalo, fornecendo o índice inicial e o comprimento.O código a seguir demonstra o uso de Array.sub.
let a1 = [| 0 .. 99 |]
let a2 = Array.sub a1 5 10
printfn "%A" a2
A saída mostra que o subarray começa no elemento 5 e contém 10 elementos.
[|5; 6; 7; 8; 9; 10; 11; 12; 13; 14|]
Matriz.acrescentar cria uma nova matriz, combinando duas matrizes existentes.
O código a seguir demonstra Array.append.
printfn "%A" (Array.append [| 1; 2; 3|] [| 4; 5; 6|])
A saída do código anterior é da seguinte maneira.
[|1; 2; 3; 4; 5; 6|]
Array.Choose seleciona elementos de uma matriz para incluir um novo array.O código a seguir demonstra Array.choose.Observe que o tipo de elemento da matriz não precisa corresponder ao tipo do valor retornado no tipo de opção.Neste exemplo, o tipo de elemento é int e a opção é o resultado de uma funçãopolinomial, elem*elem - 1, como um número de ponto flutuante .
printfn "%A" (Array.choose (fun elem -> if elem % 2 = 0 then
Some(float (elem*elem - 1))
else
None) [| 1 .. 10 |])
A saída do código anterior é da seguinte maneira.
[|3.0; 15.0; 35.0; 63.0; 99.0|]
Array.Collect executa uma função de especificada em cada elemento da matriz de um array existente e os elementos gerados pela função de coleta e as combina em uma nova matriz.O código a seguir demonstra Array.collect.
printfn "%A" (Array.collect (fun elem -> [| 0 .. elem |]) [| 1; 5; 10|])
A saída do código anterior é da seguinte maneira.
[|0; 1; 0; 1; 2; 3; 4; 5; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10|]
Array.Concat leva uma sequência de arrays e as combina em um único array.O código a seguir demonstra 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))
A saída do código anterior é da seguinte maneira.
[|(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 usa uma condição de booliano função e gera uma nova matriz que contém apenas os elementos da matriz de entrada para o qual a condição for verdadeira.O código a seguir demonstra Array.filter.
printfn "%A" (Array.filter (fun elem -> elem % 2 = 0) [| 1 .. 10|])
A saída do código anterior é da seguinte maneira.
[|2; 4; 6; 8; 10|]
Array.rev gera uma nova matriz, invertendo a ordem de um array existente.O código a seguir demonstra Array.rev.
let stringReverse (s: string) =
System.String(Array.rev (s.ToCharArray()))
printfn "%A" (stringReverse("!dlrow olleH"))
A saída do código anterior é da seguinte maneira.
"Hello world!"
Você pode facilmente combinar funções do módulo do array que transformam os arrays, usando o operador de pipeline (| >), conforme mostrado no exemplo a seguir.
[| 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"
A saída é
[|100; 36; 16; 4|]
Matrizes multidimensionais
Uma matriz multidimensional pode ser criada, mas não há nenhuma sintaxe para escrever um literal de matriz multidimensional.Use o operadorarray2D para criar uma matriz de uma sequência de seqüências de elementos de matriz. As seqüências podem ser literais de matriz ou lista.Por exemplo, o código a seguir cria uma matriz bidimensional.
let my2DArray = array2D [ [ 1; 0]; [0; 1] ]
Você também pode usar a funçãoArray2D.init para inicializar conjuntos de duas dimensões e semelhantes funções estão disponíveis para matrizes de três e quatro dimensões. Essas funções utilizam uma função que é usado para criar os elementos.Para criar uma matriz bidimensional que contém elementos é definida como um valor inicial em vez de especificar uma função, use o Array2D.criarfunção, que também está disponível para conjuntos de dimensões de até quatro. Primeiro, o exemplo de código a seguir mostra como criar uma matriz de matrizes que contêm os elementos desejados e, em seguida, usa Array2D.init para gerar a matriz bidimensional desejada.
let arrayOfArrays = [| [| 1.0; 0.0 |]; [|0.0; 1.0 |] |]
let twoDimensionalArray = Array2D.init 2 2 (fun i j -> arrayOfArrays.[i].[j])
Matriz de indexação e a aplicação de fatias de sintaxe é suportada por matrizes até a classificar 4.Quando você especifica um índice em várias dimensões, você use vírgulas para separar os índices, conforme ilustrado no exemplo de código a seguir.
twoDimensionalArray.[0, 1] <- 1.0
O tipo de uma matriz bidimensional é escrito como <type>[,] (por exemplo, int[,], double[,]), e o tipo de uma matriz tridimensional é escrito como <type>[,,], e assim por diante para conjuntos de dimensões maiores.
Apenas um subconjunto das funções disponíveis para matrizes unidimensionais também está disponível para matrizes multidimensionais.Para obter mais informações, consulte Módulo de Collections.Array (F#), Módulo de Collections.Array2D (F#), Módulo de Collections.Array3D (F#) e Módulo de Collections.Array4D (F#).
booliano Funções em Arrays
As funções array. Exists e Array.exists2teste elementos em matrizes de um ou dois, respectivamente. Essas funções usam umafunção de testee retornam true se não houver um elemento (ou o par de elemento para Array.exists2) que satisfaça à condição.
O código a seguir demonstra o uso de Array.exists e Array.exists2.Nesses exemplos, novas funções são criadas pela aplicação de apenas um dos argumentos, nesses casos, oargumentode função.
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|])
A saída do código anterior é da seguinte maneira.
true
false
false
true
Da mesma forma, a funçãoArray.forall testa uma matriz para determinar se todos os elementos satisfaz uma condição booliano . A variação Array.forall2 faz a mesma coisa usando umafunção boolianoque envolve os elementos de duas matrizes de tamanho igual. O código a seguir ilustra o uso dessas funções.
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 |])
A saída para esses exemplos é o seguinte.
false
true
true
false
A pesquisa de Arrays
Array.Find usa umafunção de boolianoe retorna o primeiro elemento para o qual a função retorna true, ou gera uma KeyNotFoundException se nenhum elemento que satisfaça a condição for encontrado. Array.findIndex é parecido com Array.find, exceto que ele retorna o índice do elemento, em vez do próprio elemento.
O seguinte código usa Array.find e Array.findIndex para localizar um número que é um quadrado perfeito e o cubo perfeito.
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
A saída é da seguinte maneira.
The first element that is both a square and a cube is 64 and its index is 62.
Array.tryFind é parecido com Array.find, exceto que o seu resultado é um tipo de opção e ela retorna None se for encontrado nenhum elemento.Array.tryFinddeve ser usado em vez de Array.find quando você não souber se um elemento correspondente está na matriz.Da mesma forma, Array.tryFindIndex é parecido com Array.findIndex , exceto que o tipo de opção é o valor retornado.Não se for encontrado nenhum elemento, a opção é None.
O código a seguir demonstra o uso de Array.tryFind.Esse código depende do código anterior.
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 |]
A saída é da seguinte maneira.
Found an element: 1
Found an element: 729
Use Array.tryPick quando você precisa transformar um elemento, além de encontrá-las.O resultado é o primeiro elemento para o qual a função retorna o elemento transformado como um valor de opção, ou None caso seja encontrado nenhum elemento tal.
O código a seguir mostra o uso de Array.tryPick.Neste maiúsculas e minúsculas, em vez de uma expressão lambda, várias funções do auxiliar de local são definidas para simplificar o código.
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 |]
A saída é da seguinte maneira.
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.
Executar cálculos em Arrays
O Array.averagefunção retorna a média de cada elemento em uma matriz. Ele é limitado aos tipos de elemento que suportam divisão exata por um inteiro, que inclui os tipos de ponto flutuante mas tipos não integral.O Array.averageByfunção retorna a média dos resultados de chamar uma função em cada elemento. Para uma matriz do tipo integral, você pode usar Array.averageBy e tem a funçãoconverter cada elemento em um tipo de ponto flutuante para a computação.
Use Array.max ou Array.min para obter o elemento máximo ou mínimo, se aceitar o tipo de elemento.Da mesma forma, Array.maxBy e Array.minBy permitem uma função a ser executado pela primeira vez, talvez para transformar a um tipo que ofereça suporte a comparação.
Array.Sum adiciona os elementos de uma matriz, e Array.sumBy chama uma função em cada elemento e adiciona os resultados em conjunto.
Para executar uma função em cada elemento em uma matriz sem armazenar os valores de retorno, use Array.iter.Para uma função que envolve duas matrizes de tamanho igual, use Array.iter2.Se você também precisará manter uma matriz dos resultados da função, use mapa ou Array.map2, que opera em duas matrizes, ao mesmo tempo.
As variações Array.iteri e Array.iteri2 permitem que o índice do elemento estar envolvidos na computação; o mesmo vale para Array.mapi e Array.mapi2.
As funções Array.fold, Array.foldBack, Array.reduce, Array.reduceBack, Array.scan, e Array.scanBackexecutar os algoritmos que envolvem todos os elementos de uma matriz. Da mesma forma, as variações Array.fold2 e Array.foldBack2 executar cálculos em duas matrizes.
Essas funções para a realização de computações correspondem às funções do mesmo nome no lista módulo.Para exemplos de uso , consulte Listas (F#).
A modificação de Arrays
Set define um elemento com um valor especificado.Array.Fill define um intervalo de elementos em uma matriz com um valor especificado.O código a seguir fornece um exemplo de Array.fill.
let arrayFill1 = [| 1 .. 25 |]
Array.fill arrayFill1 2 20 0
printfn "%A" arrayFill1
A saída é da seguinte maneira.
[|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|]
Você pode usar Array.blit para copiar uma subseção de um array para outro array.
Converter para e de outros tipos de
Array.ofList cria uma matriz em uma lista.Array.ofSeq cria uma matriz de uma sequência.Array.toList e Array.toSeqconverter a esses outros tipos de coleção do tipo de matriz.
Classificação de matrizes
Use array. Sort para classificar uma matriz, usando a funçãode comparação genérico.Use Array.sortBy especificar uma função que gera um valor, conhecido como um chave, para classificar usando a função de comparação genérico na chave.Use Array.sortWith se você desejar fornecer uma comparação personalizada de função.Array.sort, Array.sortBy, e Array.sortWith todos retornam a matriz classificada como uma nova matriz.As variações Array.sortInPlace, Array.sortInPlaceBy, e Array.sortInPlaceWith modificam a matriz existente em vez de retornar uma nova.
Arrays e tuplas
As funções Array.zip e descompactarconverter matrizes de pares de tupla para tuplas de arrays e vice-versa. Array.zip3 e Array.unzip3 são semelhantes, exceto que eles funcionam com tuplas de três elementos ou tuplas de três matrizes.
Computações paralelas em Arrays
O móduloArray.Parallel contém funções para a realização de computações paralelas em arrays. Este módulo não está disponível em aplicativos que versões de destino do.NET Framework anterior à versão 4.