F # - Arrays

Os arrays são coleções mutáveis, baseadas em zero e de tamanho fixo de elementos de dados consecutivos que são todos do mesmo tipo.

Criação de matrizes

Você pode criar arrays usando várias sintaxes e formas ou usando as funções do módulo Array. Nesta seção, discutiremos a criação de arrays sem usar as funções do módulo.

Existem três maneiras sintáticas de criar matrizes sem funções -

  • Listando valores consecutivos entre [| e |] e separados por ponto e vírgula.
  • Colocando cada elemento em uma linha separada, caso em que o separador de ponto-e-vírgula é opcional.
  • Usando expressões de sequência.

Você pode acessar os elementos da matriz usando um operador ponto (.) E colchetes ([e]).

O exemplo a seguir demonstra a criação de matrizes -

//using semicolon separator
let array1 = [| 1; 2; 3; 4; 5; 6 |]
for i in 0 .. array1.Length - 1 do
   printf "%d " array1.[i]
printfn" "

// without semicolon separator
let array2 =
   [|
      1
      2
      3
      4
      5
   |]
for i in 0 .. array2.Length - 1 do
   printf "%d " array2.[i]
printfn" "

//using sequence
let array3 = [| for i in 1 .. 10 -> i * i |]
for i in 0 .. array3.Length - 1 do
   printf "%d " array3.[i]
printfn" "

Quando você compila e executa o programa, ele produz a seguinte saída -

1 2 3 4 5 6
1 2 3 4 5
1 4 9 16 25 36 49 64 81 100

Operações básicas em matrizes

O módulo de biblioteca Microsoft.FSharp.Collections.Array oferece suporte a operações em matrizes unidimensionais.

A tabela a seguir mostra as operações básicas em Arrays -

Valor Descrição
acrescente: 'T [] →' T [] → 'T [] Cria uma matriz que contém os elementos de uma matriz seguidos pelos elementos de outra matriz.
média: ^ T [] → ^ T Retorna a média dos elementos em uma matriz.
averageBy: ('T → ^ U) →' T [] → ^ U Retorna a média dos elementos gerados pela aplicação de uma função a cada elemento de uma matriz.
blit: 'T [] → int →' T [] → int → int → unidade Lê uma variedade de elementos de um array e os grava em outro.
escolha: (opção 'T → U) →' T [] → 'U [] Aplica uma função fornecida a cada elemento de uma matriz. Retorna uma matriz que contém os resultados x para cada elemento para o qual a função retorna Some (x).
coletar: ('T →' U []) → T [] → 'U [] Aplica a função fornecida a cada elemento de uma matriz, concatena os resultados e retorna a matriz combinada.
concat: seq <'T []> →' T [] Cria uma matriz que contém os elementos de cada uma das sequências de matrizes fornecidas.
cópia: 'T →' T [] Cria uma matriz que contém os elementos da matriz fornecida.
criar: int → 'T →' T [] Cria uma matriz cujos elementos são todos inicialmente o valor fornecido.
vazio: 'T [] Retorna uma matriz vazia do tipo fornecido.
existe: ('T → bool) →' T [] → bool Testa se algum elemento de uma matriz satisfaz o predicado fornecido.
existe2: ('T1 →' T2 → bool) → 'T1 [] →' T2 [] → bool Testa se algum par de elementos correspondentes de duas matrizes satisfaz a condição fornecida.
preencher: 'T [] → int → int →' T → unidade Preenche um intervalo de elementos de uma matriz com o valor fornecido.
filtro: ('T → bool) →' T [] → 'T [] Retorna uma coleção que contém apenas os elementos da matriz fornecida para a qual a condição fornecida retorna true.
encontrar: ('T → bool) →' T [] → 'T Retorna o primeiro elemento para o qual a função fornecida retorna true. Gera KeyNotFoundException se tal elemento não existir.
findIndex: ('T → bool) →' T [] → int Retorna o índice do primeiro elemento em uma matriz que satisfaça a condição fornecida. Gera KeyNotFoundException se nenhum dos elementos satisfizer a condição.
dobrar: ('Estado →' T → 'Estado) →' Estado → 'T [] →' Estado Aplica uma função a cada elemento de uma matriz, encadeando um argumento do acumulador por meio da computação. Se a função de entrada for fe os elementos da matriz forem i0 ... iN, esta função calcula f (... (fs i0) ...) iN.
fold2: ('Estado →' T1 → 'T2 →' Estado) → 'Estado →' T1 [] → 'T2 [] →' Estado Aplica uma função a pares de elementos de dois arrays fornecidos, da esquerda para a direita, encadeando um argumento do acumulador por meio da computação. As duas matrizes de entrada devem ter os mesmos comprimentos; caso contrário, ArgumentException é gerado.
foldBack: ('T →' Estado → 'Estado) →' T [] → 'Estado →' Estado Aplica uma função a cada elemento de uma matriz, encadeando um argumento do acumulador por meio da computação. Se a função de entrada for fe os elementos da matriz forem i0 ... iN, esta função calcula f i0 (... (f iN s)).
foldBack2: ('T1 →' T2 → 'Estado →' Estado) → 'T1 [] →' T2 [] → 'Estado →' Estado Aplica uma função a pares de elementos de dois arrays fornecidos, da direita para a esquerda, encadeando um argumento do acumulador por meio da computação. As duas matrizes de entrada devem ter os mesmos comprimentos; caso contrário, ArgumentException é gerado.
forall: ('T → bool) →' T [] → bool Testa se todos os elementos de uma matriz satisfazem a condição fornecida.
forall2: ('T1 →' T2 → bool) → 'T1 [] →' T2 [] → bool Testa se todos os elementos correspondentes de duas matrizes fornecidas satisfazem uma condição fornecida.
obter: 'T [] → int →' T Obtém um elemento de uma matriz.
init: int → (int → 'T) →' T [] Usa uma função fornecida para criar uma matriz da dimensão fornecida.
isEmpty: 'T [] → bool Testa se uma matriz possui algum elemento.
iter: ('T → unidade) →' T [] → unidade Aplica a função fornecida a cada elemento de uma matriz.
iter2: ('T1 →' T2 → unidade) → 'T1 [] →' T2 [] → unidade) Aplica a função fornecida a um par de elementos de índices correspondentes em duas matrizes. As duas matrizes devem ter os mesmos comprimentos; caso contrário, ArgumentException é gerado.
iteri: (int → 'T → unidade) →' T [] → unidade Aplica a função fornecida a cada elemento de uma matriz. O inteiro passado para a função indica o índice do elemento.
iteri2: (int → 'T1 →' T2 → unidade) → 'T1 [] →' T2 [] → unidade Aplica a função fornecida a um par de elementos a partir de índices correspondentes em duas matrizes, passando também o índice dos elementos. As duas matrizes devem ter os mesmos comprimentos; caso contrário, um ArgumentException é gerado.
comprimento: 'T [] → int Retorna o comprimento de uma matriz. A propriedade Length faz a mesma coisa.
mapa: ('T →' U) → 'T [] →' U [] Cria uma matriz cujos elementos são os resultados da aplicação da função fornecida a cada um dos elementos de uma matriz fornecida.
mapa2: ('T1 →' T2 → 'U) →' T1 [] → 'T2 [] →' U [] Cria uma matriz cujos elementos são os resultados da aplicação da função fornecida aos elementos correspondentes de duas matrizes fornecidas. As duas matrizes de entrada devem ter os mesmos comprimentos; caso contrário, ArgumentException é gerado.
mapi: (int → 'T →' U) → 'T [] →' U [] Cria uma matriz cujos elementos são os resultados da aplicação da função fornecida a cada um dos elementos de uma matriz fornecida. Um índice inteiro passado para a função indica o índice do elemento sendo transformado.
mapi2: (int → 'T1 →' T2 → 'U) →' T1 [] → 'T2 [] →' U [] Cria uma matriz cujos elementos são os resultados da aplicação da função fornecida aos elementos correspondentes das duas coleções aos pares, passando também o índice dos elementos. As duas matrizes de entrada devem ter os mesmos comprimentos; caso contrário, ArgumentException é gerado.
máx: 'T [] →' T Retorna o maior de todos os elementos de uma matriz. Operators.max é usado para comparar os elementos.
maxBy: ('T →' U) → 'T [] →' T Retorna o maior de todos os elementos de uma matriz, comparado por Operators.max no resultado da função.
min: ('T [] →' T Retorna o menor de todos os elementos de uma matriz. Operators.min é usado para comparar os elementos.
minBy: ('T →' U) → 'T [] →' T Retorna o menor de todos os elementos de uma matriz. Operators.min é usado para comparar os elementos.
ofList: 'Lista T →' T [] Cria uma matriz da lista fornecida.
ofSeq: seq <'T> →' T [] Cria uma matriz do objeto enumerável fornecido.
partição: ('T → bool) →' T [] → 'T [] *' T [] Divide uma matriz em duas matrizes, uma contendo os elementos para os quais a condição fornecida retorna true, e o outro contendo aqueles para os quais ele retorna false.
permutar: (int → int) → 'T [] →' T [] Permuta os elementos de uma matriz de acordo com a permutação especificada.
escolha: ('T →' opção U) → 'T [] →' U Aplica a função fornecida a elementos sucessivos de uma matriz fornecida, retornando o primeiro resultado onde a função retorna Some (x) para algum x. Se a função nunca retorna Some (x), KeyNotFoundException é gerado.
reduzir: ('T →' T → 'T) →' T [] → 'T Aplica uma função a cada elemento de uma matriz, encadeando um argumento do acumulador por meio da computação. Se a função de entrada for fe os elementos da matriz forem i0 ... iN, esta função calcula f (... (f i0 i1) ...) iN. Se a matriz tiver tamanho zero, ArgumentException será gerado.
reduzirBack: ('T →' T → 'T) →' T [] → 'T Aplica uma função a cada elemento de uma matriz, encadeando um argumento do acumulador por meio da computação. Se a função de entrada for fe os elementos forem i0 ... iN, esta função calcula f i0 (... (f iN-1 iN)). Se a matriz tiver tamanho zero, ArgumentException será gerado.
rev: 'T [] →' T [] Inverte a ordem dos elementos em uma matriz fornecida.
varredura: ('Estado →' T → 'Estado) →' Estado → 'T [] →' Estado []) Comporta-se como dobra, mas retorna os resultados intermediários junto com os resultados finais.
scanBack: ('T →' Estado → 'Estado) →' T [] → 'Estado →' Estado [] Se comporta como foldBack, mas retorna os resultados intermediários junto com os resultados finais.
definir: 'T [] → int →' T → unidade Define um elemento de uma matriz.
classificar: 'T [] →' T [] Classifica os elementos de uma matriz e retorna uma nova matriz. Operators.compare é usado para comparar os elementos.
sortBy: ('T →' Tecla) → 'T [] →' T [] Classifica os elementos de uma matriz usando a função fornecida para transformar os elementos no tipo no qual a operação de classificação se baseia e retorna uma nova matriz. Operators.compare é usado para comparar os elementos.
sortInPlace: 'T [] → unidade Classifica os elementos de uma matriz alterando a matriz no local, usando a função de comparação fornecida. Operators.compare é usado para comparar os elementos.
sortInPlaceBy: (tecla 'T →') → 'T [] → unidade Classifica os elementos de uma matriz alterando a matriz no local, usando a projeção fornecida para as chaves. Operators.compare é usado para comparar os elementos.
sortInPlaceWith: ('T →' T → int) → 'T [] → unidade Classifica os elementos de uma matriz usando a função de comparação fornecida para alterar a matriz no local.
sortWith: ('T →' T → int) → 'T [] →' T [] Classifica os elementos de uma matriz usando a função de comparação fornecida e retorna uma nova matriz.
sub: 'T [] → int → int →' T [] Cria uma matriz que contém o subintervalo fornecido, que é especificado pelo índice inicial e comprimento.
soma: 'T [] → ^ T Retorna a soma dos elementos da matriz.
sumBy: ('T → ^ U) →' T [] → ^ U Retorna a soma dos resultados gerados pela aplicação de uma função a cada elemento de uma matriz.
toList: 'T [] →' T list Converte a matriz fornecida em uma lista.
toSeq: 'T [] → seq <' T> Vê a matriz fornecida como uma sequência.
tryFind: ('T → bool) →' T [] → 'opção T Retorna o primeiro elemento na matriz fornecida para o qual a função fornecida retorna true. DevoluçõesNone se tal elemento não existir.
tryFindIndex: ('T → bool) →' T [] → opção int Retorna o índice do primeiro elemento em uma matriz que satisfaça a condição fornecida.
tryPick: ('T →' opção U) → 'T [] →' opção U Aplica a função fornecida a elementos sucessivos da matriz fornecida e retorna o primeiro resultado onde a função retorna Some (x) para algum x. Se a função nunca retorna Some (x),None é devolvido.
descompacte: ('T1 *' T2) [] → 'T1 [] *' T2 [] Divide uma matriz de pares de tupla em uma tupla de duas matrizes.
unzip3: ('T1 *' T2 * 'T3) [] →' T1 [] * 'T2 [] *' T3 [] Divide um array de tuplas de três elementos em uma tupla de três arrays.
zeroCreate: int → 'T [] Cria uma matriz cujos elementos são inicialmente definidos com o valor padrão Unchecked.defaultof <'T>.
CEP: 'T1 [] →' T2 [] → ('T1 *' T2) [] Combina duas matrizes em uma matriz de tuplas que possui dois elementos. As duas matrizes devem ter comprimentos iguais; caso contrário, ArgumentException é gerado.
zip3: 'T1 [] →' T2 [] → 'T3 [] → (' T1 * 'T2 * 113' T3) [] Combina três matrizes em uma matriz de tuplas com três elementos. As três matrizes devem ter comprimentos iguais; caso contrário, ArgumentException é gerado.

Na seção seguinte, veremos os usos de algumas dessas funcionalidades.

Criação de matrizes usando funções

O módulo Array oferece várias funções que criam um array desde o início.

  • o Array.empty função cria uma nova matriz vazia.

  • o Array.create função cria uma matriz de um tamanho especificado e define todos os elementos para determinados valores.

  • o Array.init function cria um array, dada uma dimensão e uma função para gerar os elementos.

  • o Array.zeroCreate função cria uma matriz na qual todos os elementos são inicializados com o valor zero.

  • o Array.copy função cria uma nova matriz que contém elementos que são copiados de uma matriz existente.

  • o Array.sub função gera uma nova matriz a partir de um subintervalo de uma matriz.

  • o Array.append função cria um novo array combinando dois arrays existentes.

  • o Array.choose função seleciona elementos de uma matriz para incluir em uma nova matriz.

  • o Array.collect function executa uma função especificada em cada elemento da matriz de uma matriz existente e, a seguir, coleta os elementos gerados pela função e os combina em uma nova matriz.

  • o Array.concat função pega uma sequência de matrizes e as combina em uma única matriz.

  • o Array.filter function recebe uma função de condição booleana e gera uma nova matriz que contém apenas os elementos da matriz de entrada para os quais a condição é verdadeira.

  • o Array.rev função gera um novo array invertendo a ordem de um array existente.

Os exemplos a seguir demonstram essas funções -

Exemplo 1

(* using create and set *)
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)
printfn " "

(* empty array *)
let array2 = Array.empty
printfn "Length of empty array: %d" array2.Length

let array3 = Array.create 10 7.0
printfn "Float Array: %A" array3

(* using the init and zeroCreate *)
let array4 = Array.init 10 (fun index -> index * index)
printfn "Array of squares: %A" array4

let array5 : float array = Array.zeroCreate 10
let (myZeroArray : float array) = Array.zeroCreate 10
printfn "Float Array: %A" array5

Quando você compila e executa o programa, ele produz a seguinte saída -

0 1 2 3 4 5 6 7 8 9
Length of empty array: 0
Float Array: [|7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0|]
Array of squares: [|0; 1; 4; 9; 16; 25; 36; 49; 64; 81|]
Float Array: [|0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0|]

Exemplo 2

(* creating subarray from element 5 *)
(* containing 15 elements thereon *)

let array1 = [| 0 .. 50 |]
let array2 = Array.sub array1 5 15
printfn "Sub Array:"
printfn "%A" array2

(* appending two arrays *)
let array3 = [| 1; 2; 3; 4|]
let array4 = [| 5 .. 9 |]
printfn "Appended Array:"
let array5 = Array.append array3 array4
printfn "%A" array5

(* using the Choose function *)
let array6 = [| 1 .. 20 |]
let array7 = Array.choose (fun elem -> if elem % 3 = 0 then
   Some(float (elem))
      else
   None) array6

printfn "Array with Chosen elements:"
printfn "%A" array7

(*using the Collect function *)
let array8 = [| 2 .. 5 |]
let array9 = Array.collect (fun elem -> [| 0 .. elem - 1 |]) array8
printfn "Array with collected elements:"
printfn "%A" array9

Quando você compila e executa o programa, ele produz a seguinte saída -

Sub Array:
[|5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19|]
Appended Array:
[|1; 2; 3; 4; 5; 6; 7; 8; 9|]
Array with Chosen elements:
[|3.0; 6.0; 9.0; 12.0; 15.0; 18.0|]
Array with collected elements:
[|0; 1; 0; 1; 2; 0; 1; 2; 3; 0; 1; 2; 3; 4|]

Pesquisando matrizes

o Array.find function recebe uma função booleana e retorna o primeiro elemento para o qual a função retorna true; caso contrário, gera uma KeyNotFoundException.

o Array.findIndex A função funciona de maneira semelhante, exceto que retorna o índice do elemento em vez do próprio elemento.

O exemplo a seguir demonstra isso.

A Microsoft fornece este exemplo de programa interessante, que encontra o primeiro elemento no intervalo de um determinado número que é tanto um quadrado perfeito quanto um cubo perfeito -

let array1 = [| 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) array1

let index = Array.findIndex (fun elem -> isPerfectSquare elem && isPerfectCube elem) array1

printfn "The first element that is both a square and a cube is %d and its index is %d." element index

Quando você compila e executa o programa, ele produz a seguinte saída -

The first element that is both a square and a cube is 64 and its index is 62.