Executar operações em listas
Quando você armazena muitos itens em uma lista, geralmente, realiza operações em toda a lista ou parte dela. O módulo de lista contém muitas operações úteis que permitem fazer exatamente isso.
Funções do módulo de listas
Além das propriedades, há um módulo de lista repleto de funções que operam em uma lista. As funções podem executar operações comumente usadas, como localizar, filtrar, classificar, realizar operações matemáticas e muito mais.
Iteração
Iterar significa passar por cada elemento de uma lista, do ponto inicial ao ponto final. Para a iteração, há duas funções particularmente interessantes:
iter(): essa função permite iterar sobre cada item de uma lista, conforme mostrado aqui:let cards = [ 1 .. 5 ] List.iter(fun i -> printfn "%i" i) cards // 1 2 3 4 5A função
iter()assume uma função. No código anterior, você está fornecendo uma função anônima usando a palavra-chavefun. Essa função assume um parâmetro que representa o item atual conforme ele está sendo iterado. O código a seguir é equivalente a escrever o seguinte código com um loop:for i in cards do printfn "%i" imap(): essa função é semelhante aiter(), mas permite transformar o que você tem. Aqui está um exemplo:type Person = { FirstName: string; LastName: string } let people = [ { FirstName="Albert"; LastName= "Einstein" } { FirstName="Marie"; LastName="Curie" } ] let nobelPrizeWinners = List.map (fun person -> person.FirstName + person.LastName) people printfn "%A" nobelPrizeWinners // ["Albert Einstein"; "Marie Curie"]No código anterior, a lista de objetos
Personé transformada em uma lista de cadeias de caracteres.
Filtrar
A função filter() também assume uma função como parâmetro, mas seu objetivo é definir quais elementos serão mantidos. Se a expressão for avaliada como true, o elemento será mantido. Se a expressão for false, o elemento não fará parte da lista filtrada. No exemplo a seguir, uma lista é filtrada para manter somente os itens cujo valor é divisível por dois:
let cards = [ 1 .. 5 ]
let filteredList = List.filter(fun i-> i % 2 = 0) cards
List.iter(fun i -> printfn "item %i" i) filteredList // item 2 item 4
A lista filteredList agora contém apenas os elementos que retornaram true ao serem avaliados por i % 2 = 0, que são 2 e 4.
Classificar
Classificar listas é algo que você provavelmente fará com frequência. Aqui estão três funções que você pode achar úteis ao classificar listas:
sort(), classifica em ordem crescente. Aqui está um exemplo:let list = [2; 1; 5; 3] let sortedList = List.sort list // 1 2 3 5sortBy(): com essa função, a ideia é apontar uma chave para classificar. Digamos que você tenha uma lista de pessoas, e cada registro tenha os camposnameeage. Você pode apontar para classificar porage, por exemplo. Essa função usa uma função na qual você aponta a chave. Outra chave possível é o comprimento de uma cadeia de caracteres, como neste exemplo:let fruits = ["Banana"; "Apple"; "Pineapple"] let sortedFruits = List.sortBy (fun (fruit : string) -> fruit.Length) fruits // Apple, Banana, PineapplesortWith(): com essa função, você pode fornecer um comparador, pois, à primeira vista, pode não ser aparente qual dos diversos itens deve ser classificado antes de qualquer outro item. Veja alguns exemplos de código:// assume a type like so type MagicCreature = { Name : string; Level: int; Attack: int } let creatures = [ { Name="Dragon"; Level=2; Attack=20 } { Name="Orc"; Level=1; Attack=5 } { Name="Demon"; Level=2; Attack=10 } ] // comparison function, -1 = less than, 1 = larger than, 0 = equal let compareCreatures c1 c2 = if c1.Level < c2.Level then -1 else if c1.Level > c2.Level then 1 else if c1.Attack < c2.Attack then -1 else if c1.Attack > c2.Attack then 1 else 0 let sorted = List.sortWith compareCreatures creatures // { Name="Orc"; Level=1; Attack=5 }, { Name="Demon"; Level=2; Attack=10 }, { Name="Dragon"; Level=2; Attack=20 }A função
compareCreatures()de comparação anterior tenta primeiro comparar porLevel. Se o nível for igual, ela tentará comparar usandoAttack. Retornar-1significa que algo é considerado menor,1significa que é maior e0indica que é igual.
Pesquisa
Outra ação que você pode querer fazer é encontrar um elemento específico. Para fazer isso, você pode escolher entre as seguintes funções:
find(): essa função localiza o primeiro elemento que corresponde a uma determinada condição. Para usarfind(), você precisa fornecer uma função (predicado) que expresse como encontrar o item. Aqui está um exemplo:let list = [1; 2; 3; 4] let found = List.find( fun x -> x % 2 = 0) list // 2 - Only the first element that matches the condition is returned.tryFind(). Essa função usa uma função (predicado) que informa como encontrar o valor e qual é a lista a ser examinada. Ela retorna uma opção. Aqui está o modo de usá-la:let findValue aValue aList = let found = aList |> List.tryFind(fun item -> item = aValue) match found with | Some value -> printfn "%i" value | None -> printfn "Not found" findValue 1 list // 1 findValue 5 list // Not foundNo código anterior, você envia um valor para comparar à sua lista. Se for encontrado, retornará
Some. Se não for encontrado, ele retornaráNone.tryFindIndex(). Assim comotryFind(), essa função retorna uma opção e assume uma função (predicado) avaliada como um booliano. Esta é a aparência do código:let found = List.tryFindIndex(fun x -> x = 4) list match found with | Some index -> printfn "%i" index | None -> printfn "Not found"
Operações aritméticas
Realizar operações matemáticas em uma lista pode ser algo valioso. Entre as várias opções de funções da API de Lista, estas são as três mais úteis:
sum(): Ao usar essa função, você itera sobre cada item para somar todos os valores da lista. Aqui está o modo de usá-la:let sum = List.sum [1 .. 5] // sum = 15sumBy(): com essa função, a ideia é destacar como somar os valores. Uma maneira de fazer isso é destacar quais campos somar, como no seguinte exemplo:type OrderItem = { Name: string; Cost:int } let orderItems = [ { Name="XBox"; Cost=500 } { Name="Book"; Cost=10 } { Name="Movie ticket"; Cost=7 } ] let sum = List.sumBy(fun item -> item.Cost) orderItems printfn "%i" sum // 517No código anterior, é apontado o campo
Cost, e cada item no campo é adicionado ao total.average(): essa função é semelhante asum(), pois ela opera em uma lista de números, mas com duas diferenças:- Ela espera que os dados sejam números de ponto flutuante, e não inteiros.
- Ela calcula uma média, em vez de uma soma.
Aqui está um exemplo:
let numbers = [ 1.0; 2.5; 3.0 ] let avg = List.average numbers printfn "%f" avg // 2.166667averageBy(): assim comosumBy(),averageBy()assume uma função na qual você especifica o valor desejado. Aqui está um exemplo:type WeatherMeasurement = { Date: string; Temperature: float } let measurements = [ { Date="07/20/2021"; Temperature=21.3 } { Date="07/21/2021"; Temperature=23.2 } { Date="07/22/2021"; Temperature=20.7 } ] let avgBy = List.averageBy(fun m -> m.Temperature) measurements printfn "%f" avgBy // 21.733333