Realización de operaciones en listas
Si almacena muchos elementos en una lista, a menudo realizará operaciones en parte o en la totalidad de la lista. El módulo de lista contiene muchas operaciones útiles que le permiten hacerlo.
Funciones del módulo de lista
Además de las propiedades, hay un módulo repleto de funciones para realizar en una lista. Las funciones pueden realizar operaciones de uso frecuente, como buscar, filtrar, ordenar, realizar operaciones matemáticas, etc.
Iteración
"Iterar" significa recorrer cada elemento de una lista desde un punto inicial hasta un punto final. Para la iteración hay dos funciones especialmente interesantes:
iter(): esta función le permite recorrer en iteración cada elemento de una lista, como se muestra aquí:let cards = [ 1 .. 5 ] List.iter(fun i -> printfn "%i" i) cards // 1 2 3 4 5La función
iter()toma una función. En el código anterior, se proporciona una función anónima mediante la palabra clavefun. Esta función toma un parámetro que representa el elemento actual a medida que se itera. Este código equivale a escribir el siguiente con un bucle:for i in cards do printfn "%i" imap(): esta función es similar aiter(), pero permite transformar lo que tiene. Veamos un ejemplo: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"]En el código anterior, la lista de objetos
Personse transforma en una lista de cadenas.
Filtro
La función filter() también toma una función como parámetro, pero su propósito es definir los elementos que se conservarán. Si la evaluación de la expresión es true, se mantiene el elemento. Si la expresión es false, el elemento no formará parte de la lista filtrada. En el ejemplo siguiente, se filtra una lista para mantener solo los elementos cuyo valor es divisible por dos:
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
Ahora, la lista filteredList solo contiene los elementos que han devuelto true al evaluarse según i % 2 = 0, es decir, 2 y 4.
Ordenar
Ordenar listas es algo que probablemente haga con frecuencia. Estas son tres funciones que pueden resultar útiles al ordenar listas:
sort()ordena de forma ascendente. Veamos un ejemplo:let list = [2; 1; 5; 3] let sortedList = List.sort list // 1 2 3 5sortBy(): con esta función, la idea es indicar una clave por la que ordenar. Supongamos que tiene una lista de personas y cada registro tiene los camposnameyage. A continuación, puede indicar que se ordene porage, por ejemplo. Esta función toma una función en la que se señala la clave. Otra clave podría ser la longitud de una cadena, como en este ejemplo:let fruits = ["Banana"; "Apple"; "Pineapple"] let sortedFruits = List.sortBy (fun (fruit : string) -> fruit.Length) fruits // Apple, Banana, PineapplesortWith(): con esta función, puede proporcionar una función de comparador, ya que es posible que no sea evidente al principio cuál de varios elementos debe ordenarse antes que cualquier otro. A continuación, se ponen ejemplos 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 }La función de comparación anterior,
compareCreatures(), intenta comparar primero medianteLevel. Si el nivel es igual, intenta comparar medianteAttack. Devuelve-1si algo se considera más pequeño,1si es mayor y0si es igual.
Buscar
Otra cosa que puede querer hacer es buscar un elemento específico. Para ello, puede elegir entre las funciones siguientes:
find(): esta función busca el primer elemento que coincide con una condición determinada. Para usarfind(), debe proporcionar una función (predicado) que exprese cómo encontrar el elemento. Veamos un ejemplo: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(). Esta función toma una función (predicado) que indica cómo buscar el valor y una lista en la que buscar. Devuelve una opción. A continuación, se muestra cómo puede usarla: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 foundEn el código anterior, envía un valor para compararlo con su lista. Si se encuentra, devuelve
Some. Si no se encuentra, devuelveNone.tryFindIndex(). Al igual quetryFind(), esta función devuelve una opción y toma una función (predicado) que se evalúa como valor booleano. El código tendría el aspecto siguiente:let found = List.tryFindIndex(fun x -> x = 4) list match found with | Some index -> printfn "%i" index | None -> printfn "Not found"
Operaciones aritméticas
Realizar operaciones matemáticas en una lista puede ser útil. De las muchas funciones entre las que elegir en la API de listas, estas son las tres más útiles:
sum(): con esta función, se recorre en iteración cada elemento para sumar todos los valores de la lista. A continuación, se muestra cómo puede usarla:let sum = List.sum [1 .. 5] // sum = 15sumBy(): con esta función, la idea es indicar cómo sumar los valores. Una forma de hacerlo es indicar qué campos sumar, como en el ejemplo siguiente: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 // 517En el código anterior, se indica el campo
Costy cada elemento de ese campo se suma al total.average(): esta función es similar asum()en la medida que funciona en una lista de números, pero presenta dos diferencias:- Espera que los datos sean números de punto flotante, no enteros.
- Calcula un promedio en lugar de una suma.
Veamos un ejemplo:
let numbers = [ 1.0; 2.5; 3.0 ] let avg = List.average numbers printfn "%f" avg // 2.166667averageBy():sumBy(), al igual queaverageBy(), toma una función donde se especifica el valor que desea. Veamos un ejemplo: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