F # - Listas

Em F #, uma lista é uma série ordenada e imutável de elementos do mesmo tipo. Em certa medida, é equivalente a uma estrutura de dados de lista vinculada.

O módulo F #, Microsoft.FSharp.Collections.List,tem as operações comuns em listas. No entanto, o F # importa este módulo automaticamente e o torna acessível a todos os aplicativos F #.

Criação e inicialização de uma lista

A seguir estão as várias maneiras de criar listas -

  • Lista de uso literals.

  • Usando cons (: :) operador.

  • Usando o List.init método do módulo List.

  • Usando alguns syntactic constructs chamado List Comprehensions.

Listar literais

Nesse método, você apenas especifica uma sequência de valores delimitada por ponto-e-vírgula entre colchetes. Por exemplo -

let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]

Os contras (: :) Operador

Com este método, você pode adicionar alguns valores prefixando ou cons-ingpara uma lista existente usando o operador ::. Por exemplo -

let list2 = 1::2::3::4::5::6::7::8::9::10::[];;

[] denota uma lista vazia.

Método de inicialização de lista

O método List.init do módulo List é freqüentemente usado para criar listas. Este método tem o tipo -

val init : int -> (int -> 'T) -> 'T list

O primeiro argumento é o comprimento desejado da nova lista e o segundo argumento é uma função inicializadora, que gera itens na lista.

Por exemplo,

let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))

Aqui, a função de índice gera a lista.

Compreensão de lista

Compreensões de lista são construções sintáticas especiais usadas para gerar listas.

A sintaxe de compreensão de lista F # vem em duas formas - intervalos e geradores.

Os intervalos têm as construções - [início .. fim] e [início .. etapa .. fim]

Por exemplo,

let list3 = [1 .. 10]

Geradores têm a construção - [para x na coleção do ... rendimento expr]

Por exemplo,

let list6 = [ for a in 1 .. 10 do yield (a * a) ]

Enquanto o yield palavra-chave coloca um único valor em uma lista, a palavra-chave, yield!, coloca uma coleção de valores na lista.

A função a seguir demonstra os métodos acima -

Exemplo

(* 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

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

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]

Propriedades do tipo de dados da lista

A tabela a seguir mostra várias propriedades do tipo de dados da lista -

Propriedade Tipo Descrição
Cabeça 'T O primeiro elemento.
Vazio 'T list Uma propriedade estática que retorna uma lista vazia do tipo apropriado.
Está vazia bool true se a lista não tiver elementos.
Item 'T O elemento no índice especificado (baseado em zero).
comprimento int O número de elementos.
Rabo 'T list A lista sem o primeiro elemento.

O exemplo a seguir mostra o uso dessas propriedades -

Exemplo

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))

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

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

Operadores básicos na lista

A tabela a seguir mostra as operações básicas no tipo de dados de lista -

Valor Descrição
acrescentar: 'Lista T →' Lista T → 'Lista T Retorna uma nova lista que contém os elementos da primeira lista seguidos pelos elementos da segunda.
média: 'Lista T → ^ T Retorna a média dos elementos da lista.
averageBy: ('T → ^ U) →' Lista T → ^ U Retorna a média dos elementos gerados pela aplicação da função a cada elemento da lista.
escolha: ('T →' opção U) → 'lista T →' lista U Aplica a função fornecida a cada elemento da lista. Retorna a lista composta dos resultados de cada elemento onde a função retornaSome.
coletar: ('T →' lista U) → 'lista T →' lista U Para cada elemento da lista, aplica-se a função fornecida. Concatena todos os resultados e retorna a lista combinada.
concat: seq <'lista T> →' lista T Retorna uma nova lista que contém os elementos de cada uma das listas em ordem.
vazio: 'T list Retorna uma lista vazia do tipo fornecido.
existe: ('T → bool) →' Lista T → bool Testa se algum elemento da lista satisfaz o predicado fornecido.
existe2: ('T1 →' T2 → bool) → 'lista T1 →' lista T2 → bool Testa se algum par de elementos correspondentes das listas satisfaz o predicado fornecido.
filtro: ('T → bool) →' Lista T → 'Lista T Retorna uma nova coleção contendo apenas os elementos da coleção para os quais o predicado dado retorna true.
localizar: ('T → bool) →' Lista T → 'T Retorna o primeiro elemento para o qual a função dada retorna true.
findIndex: ('T → bool) →' lista T → int Retorna o índice do primeiro elemento da lista que satisfaz o predicado fornecido.
dobrar: ('Estado →' T → 'Estado) →' Estado → 'Lista T →' Estado Aplica uma função a cada elemento da coleção, encadeando um argumento do acumulador por meio da computação. Esta função recebe o segundo argumento e aplica a função a ele e ao primeiro elemento da lista. Em seguida, ele passa esse resultado para a função junto com o segundo elemento e assim por diante. Finalmente, ele retorna o resultado final. Se a função de entrada for fe os elementos forem i0 ... iN, então esta função calcula f (... (fs i0) i1 ...) iN.
fold2: ('Estado →' T1 → 'T2 →' Estado) → 'Estado →' lista T1 → 'lista T2 →' Estado Aplica uma função aos elementos correspondentes de duas coleções, encadeando um argumento do acumulador por meio da computação. As coleções devem ter tamanhos idênticos. Se a função de entrada é fe os elementos são i0 ... iN e j0 ... jN, então esta função calcula f (... (fs i0 j0) ...) iN jN.
foldBack: ('T →' Estado → 'Estado) →' Lista T → 'Estado →' Estado Aplica uma função a cada elemento da coleção, encadeando um argumento do acumulador por meio da computação. Se a função de entrada isf e os elementos forem i0 ... iN, então calcula f i0 (... (f iN s)).
foldBack2: ('T1 →' T2 → 'Estado →' Estado) → 'lista T1 →' lista T2 → 'Estado →' Estado Aplica uma função aos elementos correspondentes de duas coleções, encadeando um argumento do acumulador por meio da computação. As coleções devem ter tamanhos idênticos. Se a função de entrada for fe os elementos forem i0 ... iN e j0 ... jN, então esta função calcula f i0 j0 (... (f iN jN s)).
forall: ('T → bool) →' T list → bool Testa se todos os elementos da coleção satisfazem o predicado fornecido.
forall2: ('T1 →' T2 → bool) → 'lista T1 →' lista T2 → bool Testa se todos os elementos correspondentes da coleção satisfazem o predicado fornecido em pares.
head: 'T list →' T Retorna o primeiro elemento da lista.
init: int → (int → 'T) →' lista T Cria uma lista chamando o gerador fornecido em cada índice.
isEmpty: 'T list → bool Devoluções true se a lista não contém elementos, false de outra forma.
iter: ('T → unidade) →' Lista T → unidade Aplica a função fornecida a cada elemento da coleção.
iter2: ('T1 →' T2 → unidade) → 'lista T1 →' lista T2 → unidade Aplica a função fornecida a duas coleções simultaneamente. As coleções devem ter tamanhos idênticos.
iteri: (int → 'T → unidade) →' Lista T → unidade Aplica a função fornecida a cada elemento da coleção. O inteiro passado para a função indica o índice do elemento.
iteri2: (int → 'T1 →' T2 → unidade) → 'lista T1 →' lista T2 → unidade Aplica a função fornecida a duas coleções simultaneamente. As coleções devem ter tamanhos idênticos. O inteiro passado para a função indica o índice do elemento.
comprimento: 'T lista → int Retorna o comprimento da lista.
mapa: ('T →' U) → 'Lista T →' Lista U Cria uma nova coleção cujos elementos são os resultados da aplicação da função dada a cada um dos elementos da coleção.
map2: ('T1 →' T2 → 'U) →' lista T1 → 'lista T2 →' lista U Cria uma nova coleção cujos elementos são os resultados da aplicação da função dada aos elementos correspondentes das duas coleções aos pares.
map3: ('T1 →' T2 → 'T3 →' U) → 'lista T1 →' lista T2 → 'lista T3 →' lista U Cria uma nova coleção cujos elementos são os resultados da aplicação da função dada aos elementos correspondentes das três coleções simultaneamente.
mapi: (int → 'T →' U) → 'lista T →' lista U Cria uma nova coleção cujos elementos são os resultados da aplicação da função dada a cada um dos elementos da coleção. O índice inteiro passado para a função indica o índice (de 0) do elemento sendo transformado.
mapi2: (int → 'T1 →' T2 → 'U) →' lista T1 → 'lista T2 →' lista U Como List.mapi, mas mapeando os elementos correspondentes de duas listas de comprimento igual.
máx: 'Lista T →' T Retorna o maior de todos os elementos da lista, comparado usando Operators.max.
maxBy: ('T →' U) → 'Lista T →' T Retorna o maior de todos os elementos da lista, comparado usando Operators.max no resultado da função.
min: 'Lista T →' T Retorna o mais baixo de todos os elementos da lista, comparado usando Operators.min.
minBy: ('T →' U) → 'Lista T →' T Retorna o mais baixo de todos os elementos da lista, comparado usando Operators.min no resultado da função
enésimo: 'T lista → int →' T Índices na lista. O primeiro elemento possui índice 0.
ofArray: 'T [] →' Lista T Cria uma lista a partir da matriz fornecida.
ofSeq: seq <'T> →' lista T Cria uma nova lista a partir do objeto enumerável fornecido.
partição: ('T → bool) →' lista T * 'lista T Divide a coleção em duas coleções, contendo os elementos para os quais o predicado dado retorna true e false respectivamente.
permutar: (int → int) → 'Lista T →' Lista T Retorna uma lista com todos os elementos permutados de acordo com a permutação especificada.
escolha: ('T →' opção U) → 'Lista T →' U Aplica a função fornecida a elementos sucessivos, retornando o primeiro resultado onde a função retorna Some por algum valor.
reduzir: ('T →' T → 'T) →' Lista T → 'T Aplica uma função a cada elemento da coleção, encadeando um argumento do acumulador por meio do cálculo. Esta função aplica a função especificada aos primeiros dois elementos da lista. Em seguida, ele passa esse resultado para a função junto com o terceiro elemento e assim por diante. Finalmente, ele retorna o resultado final. Se a função de entrada for fe os elementos forem i0 ... iN, então esta função calcula f (... (f i0 i1) i2 ...) iN.
reduzVoltar: ('T →' T → 'T) →' Lista T → 'T Aplica uma função a cada elemento da coleção, encadeando um argumento do acumulador por meio da computação. Se a função de entrada isf e os elementos são i0 ... iN, então esta função calcula f i0 (... (f iN-1 iN)).
replicar: (int → 'T →' lista T) Cria uma lista chamando o gerador fornecido em cada índice.
rev: 'Lista T →' Lista T Retorna uma nova lista com os elementos em ordem reversa.
varredura: ('Estado →' T → 'Estado) →' Estado → 'Lista T →' Lista de estados Aplica uma função a cada elemento da coleção, encadeando um argumento do acumulador por meio da computação. Esta função recebe o segundo argumento e aplica a função especificada a ele e ao primeiro elemento da lista. Em seguida, ele passa esse resultado para a função junto com o segundo elemento e assim por diante. Finalmente, ele retorna a lista de resultados intermediários e o resultado final.
scanBack: ('T →' Estado → 'Estado) →' Lista T → 'Estado →' Lista de estados Semelhante a foldBack, mas retorna os resultados intermediários e finais
classificar: 'Lista T →' Lista T Classifica a lista fornecida usando Operators.compare.
sortBy: ('T →' Tecla) → 'Lista T →' Lista T Classifica a lista fornecida usando as chaves fornecidas pela projeção fornecida. As chaves são comparadas usando Operators.compare.
sortWith: ('T →' T → int) → 'Lista T →' Lista T Classifica a lista fornecida usando a função de comparação fornecida.
soma: ^ T lista → ^ T Retorna a soma dos elementos da lista.
sumBy: ('T → ^ U) →' lista T → ^ U Retorna a soma dos resultados gerados pela aplicação da função a cada elemento da lista.
cauda: 'lista T →' lista T Retorna a lista de entrada sem o primeiro elemento.
toArray: 'Lista T →' T [] Cria uma matriz da lista fornecida.
toSeq: 'Lista T → seq <' T> Vê a lista fornecida como uma sequência.
tryFind: ('T → bool) →' Lista T → 'opção T Retorna o primeiro elemento para o qual a função dada retorna true. RetornaNone se tal elemento não existir.
tryFindIndex: ('T → bool) →' Lista T → opção int Retorna o índice do primeiro elemento da lista que satisfaz o predicado fornecido. RetornaNone se tal elemento não existir.
tryPick: ('T →' opção U) → 'Lista T →' opção U Aplica a função fornecida a elementos sucessivos, retornando o primeiro resultado onde a função retorna Somepor algum valor. Se tal elemento não existir, retorneNone.
descompacte: ('T1 *' T2) lista → 'Lista T1 *' lista T2 Divide uma lista de pares em duas listas.
unzip3: ('T1 *' T2 * 'T3) lista →' lista T1 * 'lista T2 *' lista T3 Divide uma lista de triplos em três listas.
CEP: 'lista T1 →' lista T2 → lista ('T1 *' T2) Combina as duas listas em uma lista de pares. As duas listas devem ter comprimentos iguais.
zip3: 'lista T1 →' lista T2 → 'lista T3 → lista (' T1 * 'T2 *' T3) Combina as três listas em uma lista de triplos. As listas devem ter comprimentos iguais.

Os exemplos a seguir demonstram os usos das funcionalidades acima -

Exemplo 1

Este programa mostra a reversão de uma lista recursivamente -

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)

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

The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]

No entanto, você pode usar o rev função do módulo para o mesmo propósito -

let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
printfn "The reversed list: %A" (List.rev list1)

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

The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]

Exemplo 2

Este programa mostra a filtragem de uma lista usando o List.filter método -

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

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

The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Filtered list: [2; 4; 6; 8; 10]

Exemplo 3

o List.map método mapeia uma lista de um tipo para outro -

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

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

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"]

Exemplo 4

o List.append método e o operador @ anexa uma lista a outra -

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

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

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']

Exemplo 5

o List.sortmétodo classifica uma lista. oList.sum método fornece a soma dos elementos da lista e o List.average método fornece a média dos elementos da lista -

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

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

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

Uma operação "dobrar" aplica uma função a cada elemento em uma lista, agrega o resultado da função em uma variável do acumulador e retorna o acumulador como o resultado da operação dobrar.

Exemplo 6

o List.fold método aplica uma função a cada elemento da esquerda para a direita, enquanto List.foldBack aplica uma função a cada elemento da direita para a esquerda.

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 ])

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

Sum of the elements of list [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] is 55.