Compartilhar via


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.

Dd233214.collapse_all(pt-br,VS.110).gifFunçõ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

Dd233214.collapse_all(pt-br,VS.110).gifFunçõ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|]

Dd233214.collapse_all(pt-br,VS.110).gifMatrizes 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#).

Dd233214.collapse_all(pt-br,VS.110).gifbooliano 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

Dd233214.collapse_all(pt-br,VS.110).gifA 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.

Dd233214.collapse_all(pt-br,VS.110).gifExecutar 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#).

Dd233214.collapse_all(pt-br,VS.110).gifA 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.

Dd233214.collapse_all(pt-br,VS.110).gifConverter 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.

Dd233214.collapse_all(pt-br,VS.110).gifClassificaçã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.

Dd233214.collapse_all(pt-br,VS.110).gifArrays 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.

Consulte também

Outros recursos

Referência de linguagem do F#

Tipos de F#