Listas (F#)

Uma lista de F# é uma série ordenada e imutável, dos elementos do mesmo tipo.

Criando e inicializando a lista

Você pode definir uma lista explicitamente listando dos elementos, separados por ponto e vírgula e entre colchetes, como mostrado na seguinte linha de código.

let list123 = [ 1; 2; 3 ]

Você também pode colocar as quebras de linha entre elementos, caso em que o ponto e vírgula é opcional. A sintaxe do último pode resultar em um código mais legível quando as expressões de inicialização do elemento são maiores ou quando você deseja incluir um comentário para cada elemento.

let list123 = [
    1
    2
    3 ]

Normalmente, todos os elementos de lista devem ser do mesmo tipo. Uma exceção é que uma lista na qual os elementos especificados ser um tipo básico pode ter elementos que são tipos derivados. Assim, a seguir é aceitável, porque ambos Button e CheckBox derivam de Control.

let myControlList : Control list = [ new Button(); new CheckBox() ]

Você também pode definir os elementos da lista usando um intervalo indicado pelo inteiros separados pelo operador de intervalo (..), como mostra o código a seguir.

let list1 = [ 1 .. 10 ]

Você também pode definir uma lista usando uma construção de loop, como no código a seguir.

let listOfSquares = [ for i in 1 .. 10 -> i*i ]

Uma lista vazia é especificada por um par de colchetes sem nada entre eles.

// An empty list.
let listEmpty = []

Você também pode usar uma expressão de seqüência para criar uma lista. Consulte "Expressões de seqüência" em seqüências. Por exemplo, o código a seguir cria uma lista dos quadrados dos números inteiros de 1 a 10.

let squaresList = [ for i in 1 .. 10 -> i * i ]

Operadores para trabalhar com listas

Você pode anexar elementos a uma lista usando o :: (contras) operador. Se list1 é [2; 3; 4], o código a seguir cria list2 como [100; 2; 3; 4].

let list2 = 100 :: list1

Você pode concatenar listas que têm tipos compatíveis usando o @ o operador, como no código a seguir. If list1 is [2; 3; 4] and list2 is [100; 2; 3; 4 ], this code creates list3 as [2; 3; 4; 100; 2; 3; 4].

let list3 = list1 @ list2

Funções para executar operações em listas estão disponíveis na módulo lista.

Como listas no F# são imutáveis, quaisquer operações de modificação geram novas listas em vez de modificar as listas existentes.

Listas em F# são implementadas como listas vinculadas individualmente, o que significa que as operações que acessam apenas o topo da lista são O(1), e o acesso do elemento é O (n).

Propriedades

O tipo de lista suporta as seguintes propriedades:

Propriedade

Tipo

Descrição

Head

'T

O primeiro elemento.

Vazio

bool

trueSe a lista não tem nenhum elemento.

IsEmpty

bool

trueSe a lista não tem nenhum elemento.

Item

'T

O elemento no índice especificado (baseado em zero).

Comprimento

int

O número de elementos.

Cauda

'T list

A lista sem o primeiro elemento.

Estes são alguns exemplos do uso dessas propriedades.

let list1 = [ 1; 2; 3 ]

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

Usando listas

Programação com listas permite realizar operações complexas com uma pequena quantidade de código. Esta seção descreve as operações comuns nas listas são importantes para a programação funcional.

Recursividade com listas

As listas são adequadas exclusivamente para recursiva técnicas de programação. Considere uma operação que deve ser executada em todos os elementos de uma lista. Você pode fazer este recursivamente, funcionando com a cabeça da lista e, em seguida, passando a cauda da lista, que é uma lista de menor que consiste na lista original sem o primeiro elemento, novamente para o próximo nível de recursão.

Para escrever uma função recursiva, use o operador de contras (::) na correspondência de padrões que permite separar a cabeça de uma lista de cauda.

O exemplo de código a seguir mostra como usar a correspondência de padrões para implementar uma função recursiva que executa operações em uma lista.

let rec sum list =
   match list with
   | head :: tail -> head + sum tail
   | [] -> 0

O código anterior funciona bem para listas pequenas, mas para as listas maiores, ele poderia estouro da pilha. O código a seguir aprimora esse código usando um argumento de acumulador, uma técnica padrão para trabalhar com funções de recursiva. O uso do argumento acumulador torna a recursiva de cauda de função, que economiza espaço de pilha.

let sum list =
   let rec loop list acc =
       match list with
       | head :: tail -> loop tail (acc + head)
       | [] -> acc
   loop list 0

A função RemoveAllMultiples é uma função recursiva que usa duas listas. A primeira lista contém os números cujos múltiplos serão removidos e a segunda lista é a lista da qual remover os números. O código no exemplo a seguir usa essa função recursiva para eliminar todos os não-números primos de uma lista, deixando uma lista dos números primos como resultado.

let IsPrimeMultipleTest n x =
   x = n || x % n <> 0

let rec RemoveAllMultiples listn listx =
   match listn with
   | head :: tail -> RemoveAllMultiples tail (List.filter (IsPrimeMultipleTest head) listx)
   | [] -> listx


let GetPrimesUpTo n =
    let max = int (sqrt (float n))
    RemoveAllMultiples [ 2 .. max ] [ 1 .. n ]

printfn "Primes Up To %d:\n %A" 100 (GetPrimesUpTo 100)

A saída é o seguinte:

Primes Up To 100:
[2; 3; 5; 7; 11; 13; 17; 19; 23; 29; 31; 37; 41; 43; 47; 53; 59; 61; 67; 71; 73; 79; 83; 89; 97]

Funções do módulo

O módulo lista fornece funções de acessar os elementos de uma lista. O elemento head é mais rápido e mais fácil de acessar. Use a propriedade Head ou a função do módulo List.head. Você pode acessar a cauda de uma lista usando o cauda propriedade ou o List.tail função. Para localizar um elemento pelo índice, use o List.nth função. List.nthpercorre a lista. Portanto, é O (n). Se o seu código usa List.nth com freqüência, convém considerar o uso de uma matriz em vez de uma lista. Acesso ao elemento em matrizes é O(1).

Operações booleanas em listas

O List.isEmpty função determina se uma lista tiver quaisquer elementos.

O List.exists função se aplica a um valor booleano teste para elementos de uma lista e retorna true se qualquer elemento satisfizer o Test. List.exists2 é semelhante, mas opera em pares sucessivas de elementos em duas listas.

O código a seguir demonstra o uso de List.exists.

// Use List.exists to determine whether there is an element of a list satisfies a given Boolean expression.
// containsNumber returns true if any of the elements of the supplied list match 
// the supplied number.
let containsNumber number list = List.exists (fun elem -> elem = number) list
let list0to3 = [0 .. 3]
printfn "For list %A, contains zero is %b" list0to3 (containsNumber 0 list0to3)

A saída é o seguinte:

For list [0; 1; 2; 3], contains zero is true

O exemplo a seguir demonstra o uso de List.exists2.

// Use List.exists2 to compare elements in two lists.
// isEqualElement returns true if any elements at the same position in two supplied
// lists match.
let isEqualElement list1 list2 = List.exists2 (fun elem1 elem2 -> elem1 = elem2) list1 list2
let list1to5 = [ 1 .. 5 ]
let list5to1 = [ 5 .. -1 .. 1 ]
if (isEqualElement list1to5 list5to1) then
    printfn "Lists %A and %A have at least one equal element at the same position." list1to5 list5to1
else
    printfn "Lists %A and %A do not have an equal element at the same position." list1to5 list5to1

A saída é o seguinte:

Lists [1; 2; 3; 4; 5] and [5; 4; 3; 2; 1] have at least one equal element at the same position.

Você pode usar List.forall se você deseja testar se uma condição de atender a todos os elementos de uma lista.

let isAllZeroes list = List.forall (fun elem -> elem = 0.0) list
printfn "%b" (isAllZeroes [0.0; 0.0])
printfn "%b" (isAllZeroes [0.0; 1.0])

A saída é o seguinte:

true
false

Da mesma forma, List.forall2 determina se todos os elementos nas posições correspondentes em duas listas de satisfazem uma expressão booleana que envolve cada par de elementos.

let listEqual list1 list2 = List.forall2 (fun elem1 elem2 -> elem1 = elem2) list1 list2
printfn "%b" (listEqual [0; 1; 2] [0; 1; 2])
printfn "%b" (listEqual [0; 0; 0] [0; 1; 0])

A saída é o seguinte:

true
false

Operações de classificação em listas

O List.sort, List.sortBy, e List.sortWith funções classificar listas. A função de classificação determina quais dessas três funções para usar. List.sortusa a comparação de padrão genérico. Comparação genérica usa os operadores globais com base na função comparar genérico para comparar valores. Ele trabalha de maneira eficiente com uma ampla variedade de tipos de elemento, como, por exemplo, os tipos numéricos simples, tuplas, registros, uniões discriminadas, listas, matrizes e qualquer tipo que implementa IComparable. Para tipos que implementam IComparable, comparação genérica usa a CompareTo função. Comparação de genérica também funciona com seqüências de caracteres, mas usa uma ordem de classificação independente de cultura. Comparação genérica não deve ser usada em tipos sem suporte, como, por exemplo, os tipos de função. Além disso, o desempenho da comparação genérico padrão é ideal para pequenos tipos estruturados; para tipos estruturados maiores que precisam ser comparados e classificados com freqüência, considere a implementação de IComparable e fornecendo uma implementação eficiente do CompareTo método.

List.sortByusa uma função que retorna um valor que é usado como o critério de classificação, e List.sortWith usa uma função de comparação como um argumento. Essas últimas duas funções são úteis quando você estiver trabalhando com tipos que não oferecem suporte a comparação ou quando a comparação requer a semântica de comparação mais complexa, como no caso de seqüências de caracteres com reconhecimento de cultura.

O exemplo a seguir demonstra o uso de List.sort.

let sortedList1 = List.sort [1; 4; 8; -2; 5]
printfn "%A" sortedList1

A saída é o seguinte:

[-2; 1; 4; 5; 8]

O exemplo a seguir demonstra o uso de List.sortBy.

let sortedList2 = List.sortBy (fun elem -> abs elem) [1; 4; 8; -2; 5]
printfn "%A" sortedList2

A saída é o seguinte:

[1; -2; 4; 5; 8]

O exemplo a seguir demonstra o uso de List.sortWith. Neste exemplo, a função de comparação personalizada compareWidgets é usado para comparar primeiro um campo de um tipo personalizado e, em seguida, outro quando os valores do primeiro campo são iguais.

type Widget = { ID: int; Rev: int }

let compareWidgets widget1 widget2 =
   if widget1.ID < widget2.ID then -1 else
   if widget1.ID > widget2.ID then 1 else
   if widget1.Rev < widget2.Rev then -1 else
   if widget1.Rev > widget2.Rev then 1 else
   0

let listToCompare = [
    { ID = 92; Rev = 1 }
    { ID = 110; Rev = 1 }
    { ID = 100; Rev = 5 }
    { ID = 100; Rev = 2 }
    { ID = 92; Rev = 1 }
    ]

let sortedWidgetList = List.sortWith compareWidgets listToCompare
printfn "%A" sortedWidgetList

A saída é o seguinte:

  [{ID = 92;
    Rev = 1;}; {ID = 92;
                Rev = 1;}; {ID = 100;
                            Rev = 2;}; {ID = 100;
                                        Rev = 5;}; {ID = 110;
                                                    Rev = 1;}]

Operações de pesquisa nas listas

Várias operações de pesquisa são suportadas para listas. A forma mais simples, List.find, permite que você localize o primeiro elemento que coincida com uma determinada condição.

O exemplo de código a seguir demonstra o uso de List.find para localizar o primeiro número é divisível por 5 na lista.

let isDivisibleBy number elem = elem % number = 0
let result = List.find (isDivisibleBy 5) [ 1 .. 100 ]
printfn "%d " result

O resultado é 5.

Se os elementos devem ser transformados pela primeira vez, ligue para List.pick, que usa uma função que retorna uma opção e a primeira opção de procura do valor que é Some(x). Em vez de retornar o elemento List.pick retorna o resultado x. Se nenhum elemento correspondente for encontrado, List.pick lança KeyNotFoundException. O código a seguir mostra o uso de List.pick.

let valuesList = [ ("a", 1); ("b", 2); ("c", 3) ]

let resultPick = List.pick (fun elem ->
                    match elem with
                    | (value, 2) -> Some value
                    | _ -> None) valuesList
printfn "%A" resultPick

A saída é o seguinte:

"b"

Outro grupo de operações de pesquisa, List.tryFind e funções relacionadas, retornar um valor de opção. O List.tryFind função retorna o primeiro elemento de uma lista que satisfaz uma condição, se esse elemento existe, mas o valor da opção None se não. A variação List.tryFindIndex retorna o índice do elemento, se for encontrado, em vez de um elemento em si. Essas funções são ilustradas no código a seguir.

let list1d = [1; 3; 7; 9; 11; 13; 15; 19; 22; 29; 36]
let isEven x = x % 2 = 0
match List.tryFind isEven list1d with
| Some value -> printfn "The first even value is %d." value
| None -> printfn "There is no even value in the list."

match List.tryFindIndex isEven list1d with
| Some value -> printfn "The first even value is at position %d." value
| None -> printfn "There is no even value in the list."

A saída é o seguinte:

The first even value is 22.
The first even value is at position 8.

Operações aritméticas em listas

Operações aritméticas comuns como, por exemplo, soma e média são incorporadas a módulo lista. Para trabalhar com List.sum, o tipo de elemento de lista deve oferecer suporte a + operador e têm um zero value. Todos os tipos internos de aritméticos atendem a essas condições. Para trabalhar com List.average, o tipo de elemento deve oferecer suporte à divisão sem restante, o que exclui tipos integrais, mas permite flutuante tipos de ponto. O List.sumBy e List.averageBy funções utilizam uma função como um parâmetro, e os resultados da função são usados para calcular os valores da soma ou média.

O código a seguir demonstra o uso de List.sum, List.sumBy, e List.average.

// Compute the sum of the first 10 integers by using List.sum.
let sum1 = List.sum [1 .. 10]

// Compute the sum of the squares of the elements of a list by using List.sumBy.
let sum2 = List.sumBy (fun elem -> elem*elem) [1 .. 10]

// Compute the average of the elements of a list by using List.average.
let avg1 = List.average [0.0; 1.0; 1.0; 2.0]

printfn "%f" avg1

A saída é 1.000000.

O código a seguir mostra o uso de List.averageBy.

let avg2 = List.averageBy (fun elem -> float elem) [1 .. 10]
printfn "%f" avg2

A saída é 5.5.

Listas e tuplas

Listas que contêm tuplas podem ser manipuladas por zip e descompacte o funções. Essas funções combinam duas listas de valores únicos em uma lista de tuplas ou separam a uma lista de tuplas em duas listas de valores únicos. O mais simples List.zip função leva duas listas de elementos únicos e produz uma única lista de pares de tupla. Outra versão, List.zip3, leva três listas de elementos únicos e produz uma única lista de tuplas que tem três elementos. O exemplo de código a seguir demonstra o uso de List.zip.

let list1 = [ 1; 2; 3 ]
let list2 = [ -1; -2; -3 ]
let listZip = List.zip list1 list2
printfn "%A" listZip

A saída é o seguinte:

[(1, -1); (2, -2); (3; -3)]

O exemplo de código a seguir demonstra o uso de List.zip3.

let list3 = [ 0; 0; 0]
let listZip3 = List.zip3 list1 list2 list3
printfn "%A" listZip3

A saída é o seguinte:

[(1, -1, 0); (2, -2, 0); (3, -3, 0)]

O correspondente unzip versões, List.unzip e List.unzip3, levar a listas de tuplas e retorno em uma tupla, onde a primeira lista contém todos os elementos primeiro em cada tupla e a segunda lista contém o segundo elemento de cada tupla e assim por diante.

O exemplo de código a seguir demonstra o uso de List.unzip.

let lists = List.unzip [(1,2); (3,4)]
printfn "%A" lists
printfn "%A %A" (fst lists) (snd lists)

A saída é o seguinte:

([1; 3], [2; 4])
[1; 3] [2; 4]

O exemplo de código a seguir demonstra o uso de List.unzip3.

let listsUnzip3 = List.unzip3 [(1,2,3); (4,5,6)]
printfn "%A" listsUnzip3

A saída é o seguinte:

([1; 4], [2; 5], [3; 6])

Operando em elementos de lista

F# oferece suporte a uma variedade de operações em elementos de lista. A mais simples é List. iter, que permite que você chamar uma função em todos os elementos de uma lista. Variações incluem List.iter2, que permite que você executar uma operação em elementos das duas listas, iteri, que é como List.iter , exceto que o índice de cada elemento é passado como um argumento para a função que é chamada para cada elemento, e List.iteri2, que é uma combinação da funcionalidade do List.iter2 e List.iteri. O exemplo de código a seguir ilustra essas funções.

let list1 = [1; 2; 3]
let list2 = [4; 5; 6]
List.iter (fun x -> printfn "List.iter: element is %d" x) list1
List.iteri(fun i x -> printfn "List.iteri: element %d is %d" i x) list1
List.iter2 (fun x y -> printfn "List.iter2: elements are %d %d" x y) list1 list2
List.iteri2 (fun i x y ->
               printfn "List.iteri2: element %d of list1 is %d element %d of list2 is %d"
                 i x i y)
            list1 list2

A saída é o seguinte:

List.iter: element is 1
List.iter: element is 2
List.iter: element is 3
List.iteri: element 0 is 1
List.iteri: element 1 is 2
List.iteri: element 2 is 3
List.iter2: elements are 1 4
List.iter2: elements are 2 5
List.iter2: elements are 3 6
List.iteri2: element 0 of list1 is 1; element 0 of list2 is 4
List.iteri2: element 1 of list1 is 2; element 1 of list2 is 5
List.iteri2: element 2 of list1 is 3; element 2 of list2 is 6

Outra função usada com freqüência que transforma os elementos da lista é List. map, que permite que você aplicar uma função para cada elemento de uma lista e colocar todos os resultados de uma nova lista. List.map2 e List.map3 são variações assumir várias listas. Você também pode usar List.mapi e List.mapi2, se, além de elemento, a função precisa ser passado o índice de cada elemento. A única diferença entre List.mapi2 e List.mapi que List.mapi2 funciona com duas listas. O exemplo a seguir ilustra List. map.

let list1 = [1; 2; 3]
let newList = List.map (fun x -> x + 1) list1
printfn "%A" newList

A saída é o seguinte:

[2; 3; 4]

O exemplo a seguir mostra o uso de List.map2.

let list1 = [1; 2; 3]
let list2 = [4; 5; 6]
let sumList = List.map2 (fun x y -> x + y) list1 list2
printfn "%A" sumList

A saída é o seguinte:

[5; 7; 9]

O exemplo a seguir mostra o uso de List.map3.

let newList2 = List.map3 (fun x y z -> x + y + z) list1 list2 [2; 3; 4]
printfn "%A" newList2

A saída é o seguinte:

[7; 10; 13]

O exemplo a seguir mostra o uso de List.mapi.

let newListAddIndex = List.mapi (fun i x -> x + i) list1
printfn "%A" newListAddIndex

A saída é o seguinte:

[1; 3; 5]

O exemplo a seguir mostra o uso de List.mapi2.

let listAddTimesIndex = List.mapi2 (fun i x y -> (x + y) * i) list1 list2
printfn "%A" listAddTimesIndex

A saída é o seguinte:

[0; 7; 18]

List.Collect é parecido com List.map, exceto que cada elemento produz uma lista e todas essas listas são concatenadas em uma lista final. No código a seguir, cada elemento da lista gera três números. Esses são coletadas em uma lista.

let collectList = List.collect (fun x -> [for i in 1..3 -> x * i]) list1
printfn "%A" collectList

A saída é o seguinte:

[1; 2; 3; 2; 4; 6; 3; 6; 9]

Você também pode usar coloco, que leva a uma condição booleana e produz uma nova lista que consiste somente em elementos que satisfaçam a uma determinada condição.

let evenOnlyList = List.filter (fun x -> x % 2 = 0) [1; 2; 3; 4; 5; 6]

A lista resultante é [2; 4; 6].

Uma combinação do mapa e filtro, List.choose lhe permite transformar e selecione elementos ao mesmo tempo. List.chooseaplica-se a uma função que retorna uma opção para cada elemento de uma lista e retorna uma nova lista de resultados para elementos quando a função retorna o valor da opção Some.

O código a seguir demonstra o uso de List.choose Selecionar em letras maiúsculas de palavras de uma lista de palavras.

let listWords = [ "and"; "Rome"; "Bob"; "apple"; "zebra" ]
let isCapitalized (string1:string) = System.Char.IsUpper string1.[0]
let results = List.choose (fun elem ->
    match elem with
    | elem when isCapitalized elem -> Some(elem + "'s")
    | _ -> None) listWords
printfn "%A" results

A saída é o seguinte:

["Rome's"; "Bob's"]

Operando em várias listas

Listas podem ser unidas. Para unir duas listas em uma, use List.append. Para ingressar em mais de duas listas, use List.concat.

let list1to10 = List.append [1; 2; 3] [4; 5; 6; 7; 8; 9; 10]
let listResult = List.concat [ [1; 2; 3]; [4; 5; 6]; [7; 8; 9] ]
List.iter (fun elem -> printf "%d " elem) list1to10
printfn ""
List.iter (fun elem -> printf "%d " elem) listResult

Operações de varredura e dobra

Algumas operações de lista envolvem interdependências entre todos os elementos da lista. As operações de varredura e dobra são como List.iter e List.map você chamar uma função de cada elemento, mas essas operações fornecem um parâmetro adicional chamado de acumulador que transporta informações por meio de computação.

Use List.fold para executar um cálculo em uma lista.

O exemplo de código a seguir demonstra o uso de List.fold para realizar várias operações.

A lista é atravessada; o acumulador acc é um valor que é passado como o cálculo continua. O primeiro argumento leva o acumulador e o elemento de lista e retorna o resultado provisório do cálculo para esse elemento da lista. O segundo argumento é o valor inicial do acumulador.

let sumList list = List.fold (fun acc elem -> acc + elem) 0 list
printfn "Sum of the elements of list %A is %d." [ 1 .. 3 ] (sumList [ 1 .. 3 ])

// The following example computes the average of a list.
let averageList list = (List.fold (fun acc elem -> acc + float elem) 0.0 list / float list.Length)

// The following example computes the standard deviation of a list.
// The standard deviation is computed by taking the square root of the
// sum of the variances, which are the differences between each value
// and the average.
let stdDevList list =
    let avg = averageList list
    sqrt (List.fold (fun acc elem -> acc + (float elem - avg) ** 2.0 ) 0.0 list / float list.Length)

let testList listTest =
    printfn "List %A average: %f stddev: %f" listTest (averageList listTest) (stdDevList listTest)

testList [1; 1; 1]
testList [1; 2; 1]
testList [1; 2; 3]

// List.fold is the same as to List.iter when the accumulator is not used.
let printList list = List.fold (fun acc elem -> printfn "%A" elem) () list
printList [0.0; 1.0; 2.5; 5.1 ]

// The following example uses List.fold to reverse a list.
// The accumulator starts out as the empty list, and the function uses the cons operator
// to add each successive element to the head of the accumulator list, resulting in a
// reversed form of the list.
let reverseList list = List.fold (fun acc elem -> elem::acc) [] list
printfn "%A" (reverseList [1 .. 10])

As versões dessas funções que têm um dígito no nome da função operam em mais de uma lista. Por exemplo, List.fold2 executa cálculos em duas listas.

O exemplo a seguir demonstra o uso de List.fold2.

// Use List.fold2 to perform computations over two lists (of equal size) at the same time.
// Example: Sum the greater element at each list position.
let sumGreatest list1 list2 = List.fold2 (fun acc elem1 elem2 ->
                                              acc + max elem1 elem2) 0 list1 list2

let sum = sumGreatest [1; 2; 3] [3; 2; 1]
printfn "The sum of the greater of each pair of elements in the two lists is %d." sum

List.folde List.scan diferem em que List.fold retorna o valor final do parâmetro extra, mas List.scan retorna a lista dos valores intermediários (juntamente com o valor final) do parâmetro extra.

Cada uma dessas funções inclui uma variação inversa, por exemplo, List.foldBack, que difere na ordem na qual a lista é atravessada e a ordem dos argumentos. Além disso, List.fold e List.foldBack ter variações, List.fold2 e List.foldBack2, que levar duas listas de tamanho igual. A função que é executado em cada elemento pode usar elementos correspondentes das duas listas para realizar alguma ação. Os tipos de elemento das duas listas podem ser diferentes, como no exemplo a seguir, uma lista contém os valores de transação para uma conta bancária, e a outra lista contém o tipo de transação: depósito ou saque.

// Discriminated union type that encodes the transaction type.
type Transaction =
    | Deposit
    | Withdrawal

let transactionTypes = [Deposit; Deposit; Withdrawal]
let transactionAmounts = [100.00; 1000.00; 95.00 ]
let initialBalance = 200.00

// Use fold2 to perform a calculation on the list to update the account balance.
let endingBalance = List.fold2 (fun acc elem1 elem2 ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2)
                                initialBalance
                                transactionTypes
                                transactionAmounts
printfn "%f" endingBalance

Para um cálculo como somatório, List.fold e List.foldBack têm o mesmo efeito, porque o resultado não dependa na ordem de passagem. No exemplo a seguir, List.foldBack é usado para adicionar os elementos em uma lista.

let sumListBack list = List.foldBack (fun acc elem -> acc + elem) list 0
printfn "%d" (sumListBack [1; 2; 3])

// For a calculation in which the order of traversal is important, fold and foldBack have different
// results. For example, replacing fold with foldBack in the listReverse function
// produces a function that copies the list, rather than reversing it.
let copyList list = List.foldBack (fun elem acc -> elem::acc) list []
printfn "%A" (copyList [1 .. 10])

O exemplo a seguir retorna para o exemplo de conta bancária. Esse tempo é adicionado um novo tipo de transação: um cálculo de juros. Agora, o saldo final depende na ordem de transações.

type Transaction2 =
    | Deposit
    | Withdrawal
    | Interest

let transactionTypes2 = [Deposit; Deposit; Withdrawal; Interest]
let transactionAmounts2 = [100.00; 1000.00; 95.00; 0.05 / 12.0 ]
let initialBalance2 = 200.00

// Because fold2 processes the lists by starting at the head element,
// the interest is calculated last, on the balance of 1205.00.
let endingBalance2 = List.fold2 (fun acc elem1 elem2 ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2
                                | Interest -> acc * (1.0 + elem2))
                                initialBalance2
                                transactionTypes2
                                transactionAmounts2
printfn "%f" endingBalance2
// Because foldBack2 processes the lists by starting at end of the list,
// the interest is calculated first, on the balance of only 200.00.
let endingBalance3 = List.foldBack2 (fun elem1 elem2 acc ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2
                                | Interest -> acc * (1.0 + elem2))
                                transactionTypes2
                                transactionAmounts2
                                initialBalance2
printfn "%f" endingBalance3

A função List.reduce é um pouco como List.fold e List.scan, exceto que em vez de passar um acumulador separado, List.reduce usa uma função que leva dois argumentos de tipo de elemento, em vez de apenas uma e outra desses atos de argumentos como acumulador, significando que ele armazena o resultado intermediário da computação. List.reduceInicia funcionando com os primeiros elementos de lista de duas e, em seguida, usa o resultado da operação junto com o próximo elemento. Porque não é um acumulador separada que tenha seu próprio tipo List.reduce pode ser usado no lugar de List.fold somente quando o acumulador e o tipo de elemento tem o mesmo tipo. O código a seguir demonstra o uso de List.reduce. List.reducelança uma exceção se a lista fornecida não possui elementos.

No código a seguir, a primeira chamada para a expressão lambda é dado os argumentos de 2 e 4 e retorna 6 e a próxima chamada recebe os argumentos de 6 e 10, então o resultado é 16.

let sumAList list =
    try
        List.reduce (fun acc elem -> acc + elem) list
    with
       | :? System.ArgumentException as exc -> 0

let resultSum = sumAList [2; 4; 10]
printfn "%d " resultSum

Convertendo entre listas e outros tipos de coleção

O List o módulo fornece funções para converter para e de seqüências e matrizes. Para converter de ou para uma seqüência, use List.toSeq ou List.ofSeq. Para converter para ou de uma matriz, use List.toArray ou List.ofArray.

Operações adicionais

Para obter informações sobre operações adicionais em listas, consulte o tópico de referência de biblioteca Módulo de Collections.List (F#).

Consulte também

Referência

Seqüências (F#)

Opções (F#)

Outros recursos

Referência de linguagem do F#

Tipos de F#

Matrizes (F#)

Histórico de alterações

Date

History

Motivo

Outubro de 2010

Fixa a saída de um dos exemplos de código.

Comentários do cliente.