F # - Sequências
As sequências, como as listas, também representam uma coleção ordenada de valores. No entanto, os elementos em uma sequência ou expressão de sequência são calculados quando necessário. Eles não são calculados de uma só vez e, por essa razão, são usados para representar infinitas estruturas de dados.
Definindo Sequências
As sequências são definidas usando a seguinte sintaxe -
seq { expr }
Por exemplo,
let seq1 = seq { 1 .. 10 }
Criação de sequências e expressões de sequências
Semelhante às listas, você pode criar sequências usando intervalos e compreensões.
Expressões de sequência são as expressões que você pode escrever para criar sequências. Isso pode ser feito -
- Especificando o intervalo.
- Especificando o intervalo com incremento ou decremento.
- Usando o yield palavra-chave para produzir valores que se tornam parte da sequência.
- Usando o operador →.
Os exemplos a seguir demonstram o conceito -
Exemplo 1
(* Sequences *)
let seq1 = seq { 1 .. 10 }
(* ascending order and increment*)
printfn "The Sequence: %A" seq1
let seq2 = seq { 1 .. 5 .. 50 }
(* descending order and decrement*)
printfn "The Sequence: %A" seq2
let seq3 = seq {50 .. -5 .. 0}
printfn "The Sequence: %A" seq3
(* using yield *)
let seq4 = seq { for a in 1 .. 10 do yield a, a*a, a*a*a }
printfn "The Sequence: %A" seq4
Quando você compila e executa o programa, ele produz a seguinte saída -
The Sequence: seq [1; 2; 3; 4; ...]
The Sequence: seq [1; 6; 11; 16; ...]
The Sequence: seq [50; 45; 40; 35; ...]
The Sequence: seq [(1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64); ...]
Exemplo 2
O programa a seguir imprime os números primos de 1 a 50 -
(* Recursive isprime function. *)
let isprime n =
let rec check i =
i > n/2 || (n % i <> 0 && check (i + 1))
check 2
let primeIn50 = seq { for n in 1..50 do if isprime n then yield n }
for x in primeIn50 do
printfn "%d" x
Quando você compila e executa o programa, ele produz a seguinte saída -
1
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
Operações básicas na sequência
A tabela a seguir mostra as operações básicas no tipo de dados de sequência -
Valor | Descrição |
---|---|
anexar: seq <'T> → seq <' T> → seq <'T> | Envolve as duas enumerações fornecidas como uma única enumeração concatenada. |
média: seq <^ T> → ^ T | Retorna a média dos elementos na sequência. |
averageBy: ('T → ^ U) → seq <' T> → ^ U | Retorna a média dos resultados gerados pela aplicação da função a cada elemento da sequência. |
cache: seq <'T> → seq <' T> | Retorna uma sequência que corresponde a uma versão em cache da sequência de entrada. |
elenco: IEnumerable → seq <'T> | Envolve um sistema vagamente tipado. Seqüência de coleções como uma seqüência digitada. |
escolha: ('T →' opção U) → seq <'T> → seq <' 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 →' Coleção) → seq <'T> → seq <' U> | Aplica a função fornecida a cada elemento da sequência e concatena todos os resultados. |
compareWith: ('T →' T → int) → seq <'T> → seq <' T> → int | Compara duas sequências usando a função de comparação fornecida, elemento por elemento. |
concat: seq <'Coleção> → seq <' T> | Combina a enumeração de enumerações fornecida como uma única enumeração concatenada. |
countBy: ('T →' Key) → seq <'T> → seq <' Key * int> | Aplica uma função de geração de chave a cada elemento de uma sequência e retorna uma sequência que produz chaves exclusivas e seu número de ocorrências na sequência original. |
atraso: (unidade → seq <'T>) → seq <' T> | Retorna uma sequência que é construída a partir da especificação atrasada fornecida de uma sequência. |
distinto: seq <'T> → seq <' T> | Retorna uma seqüência que não contém entradas duplicadas de acordo com hash genérico e comparações de igualdade nas entradas. Se um elemento ocorrer várias vezes na sequência, as ocorrências posteriores serão descartadas. |
Distincby: ('T →' Tecla) → seq <'T> → seq <' T> | Retorna uma seqüência que não contém entradas duplicadas de acordo com o hash genérico e comparações de igualdade nas chaves retornadas pela função de geração de chave fornecida. Se um elemento ocorrer várias vezes na sequência, as ocorrências posteriores serão descartadas. |
vazio: seq <'T> | Cria uma sequência vazia. |
exatamente Um: seq <'T> →' T | Retorna o único elemento da sequência. |
existe: ('T → bool) → seq <' T> → bool | Testa se algum elemento da sequência satisfaz o predicado fornecido. |
existe2: ('T1 →' T2 → bool) → seq <'T1> → seq <' T2> → bool | Testa se algum par de elementos correspondentes das sequências de entrada satisfaz o predicado fornecido. |
filtro: ('T → bool) → seq <' T> → seq <'T> | Retorna uma nova coleção contendo apenas os elementos da coleção para os quais o predicado dado retorna true. |
encontrar: ('T → bool) → seq <' T> → 'T | Retorna o primeiro elemento para o qual a função dada retorna true. |
findIndex: ('T → bool) → seq <' T> → int | Retorna o índice do primeiro elemento para o qual a função dada retorna true. |
dobrar: ('Estado →' T → 'Estado) →' Estado → seq <'T> →' 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 for fe os elementos forem i0 ... iN, então esta função calcula f (... (fs i0) ...) iN. |
forall: ('T → bool) → seq <' T> → bool | Testa se todos os elementos da sequência satisfazem o predicado fornecido. |
forall2: ('T1 →' T2 → bool) → seq <'T1> → seq <' T2> → bool | Testa todos os pares de elementos extraídos das duas sequências para satisfazer o predicado fornecido. Se uma sequência for mais curta do que a outra, os elementos restantes da sequência mais longa serão ignorados. |
groupBy: ('T →' Tecla) → seq <'T> → seq <' Tecla * seq <'T >> | Aplica uma função de geração de chave a cada elemento de uma sequência e produz uma sequência de chaves exclusivas. Cada chave exclusiva também contém uma sequência de todos os elementos que correspondem a essa chave. |
cabeça: seq <'T> →' T | Retorna o primeiro elemento da sequência. |
init: int → (int → 'T) → seq <' T> | Gera uma nova sequência que, quando iterada, retorna elementos sucessivos chamando a função dada, até a contagem fornecida. Os resultados da chamada da função não são salvos, ou seja, a função é reaplicada conforme necessário para regenerar os elementos. A função recebe o índice do item que está sendo gerado. |
initInfinite: (int → 'T) → seq <' T> | Gera uma nova sequência que, quando iterada, retornará elementos sucessivos chamando a função dada. Os resultados da chamada da função não são salvos, ou seja, a função será reaplicada conforme necessário para regenerar os elementos. A função recebe o índice do item que está sendo gerado. |
isEmpty: seq <'T> → bool | Testa se uma sequência possui algum elemento. |
iter: ('T → unidade) → seq <' T> → unidade | Aplica a função fornecida a cada elemento da coleção. |
iter2: ('T1 →' T2 → unidade) → seq <'T1> → seq <' T2> → unidade | Aplica a função fornecida a duas coleções simultaneamente. Se uma sequência for mais curta do que a outra, os elementos restantes da sequência mais longa serão ignorados. |
iteri: (int → 'T → unidade) → seq <' 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. |
último: seq <'T> →' T | Retorna o último elemento da sequência. |
comprimento: seq <'T> → int | Retorna o comprimento da sequência. |
mapa: ('T →' U) → seq <'T> → seq <' 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. A função fornecida será aplicada conforme os elementos são exigidos usando o método MoveNext em enumeradores recuperados do objeto. |
mapa2: ('T1 →' T2 → 'U) → seq <' T1> → seq <'T2> → seq <' U> | Cria uma nova coleção cujos elementos são os resultados da aplicação da função fornecida aos pares de elementos correspondentes das duas sequências. Se uma sequência de entrada for mais curta do que a outra, os elementos restantes da sequência mais longa serão ignorados. |
mapi: (int → 'T →' U) → seq <'T> → seq <' 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. |
máx: seq <'T> →' T | Retorna o maior de todos os elementos da sequência, comparado usando Operators.max. |
maxBy: ('T →' U) → seq <'T> →' T | Retorna o maior de todos os elementos da sequência, comparado usando Operators.max no resultado da função. |
min: seq <'T> →' T | Retorna o mais baixo de todos os elementos da sequência, comparado usando Operators.min. |
minBy: ('T →' U) → seq <'T> →' T | Retorna o mais baixo de todos os elementos da sequência, comparado usando Operators.min no resultado da função. |
enésimo: int → seq <'T> →' T | Calcula o enésimo elemento na coleção. |
ofArray: 'T array → seq <' T> | Vê o array fornecido como uma sequência. |
ofList: 'Lista T → seq <' T> | Vê a lista fornecida como uma sequência. |
em pares: seq <'T> → seq <' T * 'T> | Retorna uma sequência de cada elemento na sequência de entrada e seu predecessor, com exceção do primeiro elemento que só é retornado como o predecessor do segundo elemento. |
escolha: ('T →' opção U) → seq <'T> →' U | Aplica a função fornecida a elementos sucessivos, retornando o primeiro valor onde a função retorna um Some valor. |
somente leitura: seq <'T> → seq <' T> | Cria um novo objeto de sequência que delega para o objeto de sequência fornecido. Isso garante que a sequência original não possa ser redescoberta e transformada por uma conversão de tipo. Por exemplo, se for fornecida uma matriz, a sequência retornada retornará os elementos da matriz, mas você não pode converter o objeto de sequência retornado em uma matriz. |
reduzir: ('T →' T → 'T) → seq <' T> → 'T | Aplica uma função a cada elemento da sequência, encadeando um argumento do acumulador por meio do cálculo. Comece aplicando a função aos dois primeiros elementos. Em seguida, insira esse resultado na função junto com o terceiro elemento e assim por diante. Retorne o resultado final. |
varredura: ('Estado →' T → 'Estado) →' Estado → seq <'T> → seq <' Estado> | Como Seq.fold, mas calcula sob demanda e retorna a sequência de resultados intermediários e finais. |
singleton: 'T → seq <' T> | Retorna uma sequência que produz apenas um item. |
pular: int → seq <'T> → seq <' T> | Retorna uma sequência que ignora um número especificado de elementos da sequência subjacente e, em seguida, produz os elementos restantes da sequência. |
skipWhile: ('T → bool) → seq <' T> → seq <'T> | Retorna uma sequência que, quando iterada, pula elementos da sequência subjacente enquanto o predicado fornecido retorna true, e então produz os elementos restantes da sequência. |
classificar: seq <'T> → seq <' T> | Rende uma sequência ordenada por chaves. |
sortBy: ('T →' Tecla) → seq <'T> → seq <' T> | Aplica uma função de geração de chave a cada elemento de uma sequência e produz uma sequência ordenada por chaves. As chaves são comparadas usando comparação genérica implementada por Operators.compare. |
soma: seq <^ T> → ^ T | Retorna a soma dos elementos na sequência. |
sumBy | Retorna a soma dos resultados gerados pela aplicação da função a cada elemento da sequência. |
pegar: int → seq <'T> → seq <' T> | Retorna os primeiros elementos da sequência até uma contagem especificada. |
takeWhile: ('T → bool) → seq <' T> → seq <'T> | Retorna uma sequência que, quando iterada, produz elementos da sequência subjacente enquanto o predicado fornecido retorna true, e não retorna nenhum elemento adicional. |
toArray: seq <'T> →' T [] | Cria uma matriz da coleção fornecida. |
toList: seq <'T> →' T list | Cria uma lista da coleção fornecida. |
truncar: int → seq <'T> → seq <' T> | Retorna uma sequência que, quando enumerada, não retorna mais do que um número especificado de elementos. |
tryFind: ('T → bool) → seq <' T> → 'opção T | Retorna o primeiro elemento para o qual a função dada retorna true, ou None se tal elemento não existir. |
tryFindIndex: ('T → bool) → seq <' T> → opção int | Retorna o índice do primeiro elemento na sequência que satisfaz o predicado fornecido, ou None se tal elemento não existir. |
tryPick: ('T →' opção U) → seq <'T> →' opção U | Aplica a função fornecida a elementos sucessivos, retornando o primeiro valor onde a função retorna um Some valor. |
desdobrar: (opção 'Estado →' T * 'Estado) →' Estado → seq <'T> | Retorna uma sequência que contém os elementos gerados pelo cálculo fornecido. |
onde: ('T → bool) → seq <' T> → seq <'T> | Retorna uma nova coleção contendo apenas os elementos da coleção para os quais o predicado dado retorna true. Um sinônimo para Seq.filter. |
em janela: int → seq <'T> → seq <' T []> | Retorna uma sequência que produz janelas deslizantes contendo elementos extraídos da sequência de entrada. Cada janela é retornada como uma nova matriz. |
zip: seq <'T1> → seq <' T2> → seq <'T1 *' T2> | Combina as duas sequências em uma lista de pares. As duas sequências não precisam ter comprimentos iguais - quando uma sequência se esgota, todos os elementos restantes na outra sequência são ignorados. |
zip3: seq <'T1> → seq <' T2> → seq <'T3> → seq <' T1 * 'T2 *' T3> | Combina as três sequências em uma lista de triplas. As sequências não precisam ter comprimentos iguais - quando uma sequência se esgota, todos os elementos restantes nas outras sequências são ignorados. |
Os exemplos a seguir demonstram o uso de algumas das funcionalidades acima -
Exemplo 1
Este programa cria uma sequência vazia e a preenche mais tarde -
(* Creating sequences *)
let emptySeq = Seq.empty
let seq1 = Seq.singleton 20
printfn"The singleton sequence:"
printfn "%A " seq1
printfn"The init sequence:"
let seq2 = Seq.init 5 (fun n -> n * 3)
Seq.iter (fun i -> printf "%d " i) seq2
printfn""
(* converting an array to sequence by using cast *)
printfn"The array sequence 1:"
let seq3 = [| 1 .. 10 |] :> seq<int>
Seq.iter (fun i -> printf "%d " i) seq3
printfn""
(* converting an array to sequence by using Seq.ofArray *)
printfn"The array sequence 2:"
let seq4 = [| 2..2.. 20 |] |> Seq.ofArray
Seq.iter (fun i -> printf "%d " i) seq4
printfn""
Quando você compila e executa o programa, ele produz a seguinte saída -
The singleton sequence:
seq [20]
The init sequence:
0 3 6 9 12
The array sequence 1:
1 2 3 4 5 6 7 8 9 10
The array sequence 2:
2 4 6 8 10 12 14 16 18 20
Observe que -
O método Seq.empty cria uma sequência vazia.
O método Seq.singleton cria uma sequência de apenas um elemento especificado.
O método Seq.init cria uma sequência para a qual os elementos são criados usando uma determinada função.
Os métodos Seq.ofArray e Seq.ofList <'T> criam sequências a partir de arrays e listas.
O método Seq.iter permite iterar por meio de uma sequência.
Exemplo 2
O método Seq.unfold gera uma sequência de uma função de computação que pega um estado e o transforma para produzir cada elemento subsequente na sequência.
A função a seguir produz os primeiros 20 números naturais -
let seq1 = Seq.unfold (fun state -> if (state > 20) then None else Some(state, state + 1)) 0
printfn "The sequence seq1 contains numbers from 0 to 20."
for x in seq1 do printf "%d " x
printfn" "
Quando você compila e executa o programa, ele produz a seguinte saída -
The sequence seq1 contains numbers from 0 to 20.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Exemplo 3
O método Seq.truncate cria uma sequência de outra sequência, mas limita a sequência a um número especificado de elementos.
O método Seq.take cria uma nova sequência que contém um número especificado de elementos desde o início de uma sequência.
let mySeq = seq { for i in 1 .. 10 -> 3*i }
let truncatedSeq = Seq.truncate 5 mySeq
let takeSeq = Seq.take 5 mySeq
printfn"The original sequence"
Seq.iter (fun i -> printf "%d " i) mySeq
printfn""
printfn"The truncated sequence"
Seq.iter (fun i -> printf "%d " i) truncatedSeq
printfn""
printfn"The take sequence"
Seq.iter (fun i -> printf "%d " i) takeSeq
printfn""
Quando você compila e executa o programa, ele produz a seguinte saída -
The original sequence
3 6 9 12 15 18 21 24 27 30
The truncated sequence
3 6 9 12 15
The take sequence
3 6 9 12 15