Efectuarea de operațiuni în liste

Finalizat

Atunci când stocați multe elemente într-o listă, efectuați adesea operațiuni pe o parte sau pe toată lista. Modulul listă conține multe operațiuni utile care vă permit să faceți acest lucru.

Funcții modul listă

În afară de proprietăți, există un modul listă, care este plin de funcții care operează pe o listă. Funcțiile pot efectua operațiuni utilizate frecvent, cum ar fi găsirea, filtrarea, sortarea, efectuarea de operații matematice și multe altele.

Repetare

Pentru a itera înseamnă să parcurgeți fiecare element dintr-o listă, de la un punct de plecare la un punct de sfârșit. Pentru iterație, există două funcții deosebit de interesante:

  • iter(): Această funcție vă permite să iterați peste fiecare element dintr-o listă, așa cum se arată aici:

    let cards = [ 1 .. 5 ]
    List.iter(fun i -> printfn "%i" i) cards // 1 2 3 4 5
    

    Funcția iter() preia o funcție. În codul precedent, furnizați o funcție anonimă utilizând cuvântul cheie fun. Această funcție preia un parametru care reprezintă elementul curent pe măsură ce îl parcurgeți. Următorul cod este echivalentul scrierii următorului cod cu o buclă:

    for i in cards do printfn "%i" i
    
  • map(): Această funcție este similară cu iter(), dar vă permite să transformați ceea ce aveți. Iată un exemplu:

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

    În codul anterior, lista de obiecte Person este transformată într-o listă de șiruri.

Filtru

Funcția filter() preia și o funcție ca parametru, dar scopul său este de a defini elementele pe care să le păstrați. Dacă expresia se evaluează ca true, elementul este păstrat. Dacă expresia este false, elementul nu va face parte din lista filtrată. În exemplul următor, o listă este filtrată pentru a păstra doar elementele a căror valoare este împărțită cu două:

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

Lista de filteredList conține acum doar elementele care returnează true atunci când sunt evaluate de i % 2 = 0, care este 2 și 4.

Fel

Sortarea listelor este un lucru pe care probabil că îl puteți face adesea. Iată trei funcții care pot fi utile atunci când sortați liste:

  • sort(), sortează în ordine ascendentă. Iată un exemplu:

    let list = [2; 1; 5; 3]
    let sortedList = List.sort list // 1 2 3 5 
    
  • sortBy(): Cu această funcție, ideea este să indicați o cheie după care să sortați. Să presupunem că aveți o listă de persoane, iar fiecare înregistrare are câmpurile name și age. Apoi puteți indica spre sortare după age, de exemplu. Această funcție preia o funcție în care indicați tasta. O altă cheie poate fi lungimea unui șir, ca în acest exemplu:

    let fruits = ["Banana"; "Apple"; "Pineapple"]
    let sortedFruits = List.sortBy (fun (fruit : string) -> fruit.Length) fruits // Apple, Banana, Pineapple
    
  • sortWith(): Cu această funcție, aveți posibilitatea să furnizați o funcție de comparare, deoarece este posibil să nu fie evidentă la început care dintre mai multe elemente ar trebui să fie sortată înaintea oricărui alt element. Iată un exemplu de cod:

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

    Funcția de comparație precedentă compareCreatures() încearcă mai întâi să se compare cu Level. Dacă nivelul este egal, încearcă să se compare utilizând Attack. Returnează -1 dacă ceva este considerat mai mic, 1 dacă este mai mare și 0 dacă este egal.

Un alt lucru pe care poate doriți să-l faceți este să găsiți un anumit element. Pentru a face acest lucru, puteți alege dintre următoarele funcții:

  • find(): Această funcție găsește primul element care se potrivește cu o anumită condiție. Pentru a utiliza find(), trebuie să furnizați o funcție (predicat) care vă arată cum să găsiți elementul. Iată un exemplu:

    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(). Această funcție preia o funcție (predicat) care vă arată cum să găsiți valoarea și o listă în care să căutați. Returnează o opțiune. Iată cum îl puteți utiliza:

    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 found
    

    În codul anterior, trimiteți o valoare pentru a o compara cu lista dvs. Dacă se găsește, returnează Some. Dacă nu se găsește, returnează None.

  • tryFindIndex(). La fel ca tryFind(), această funcție returnează o opțiune și preia o funcție (predicat) care se evaluează la o valoare booleană. Iată cum poate arăta codul:

    let found = List.tryFindIndex(fun x -> x = 4) list
    match found with
       | Some index -> printfn "%i" index
       | None -> printfn "Not found"
    

Operații aritmetice

Efectuarea de operații matematice pe o listă poate fi valoroasă. Printre multe funcții din care să alegeți în API-ul listă, iată cele mai utile trei:

  • sum(): utilizând această funcție, iterați peste fiecare element pentru a însuma toate valorile din listă. Iată cum îl puteți utiliza:

    let sum = List.sum [1 .. 5] // sum = 15 
    
  • sumBy(): Cu această funcție, ideea este să subliniați modul de însumare a valorilor. O modalitate de a face acest lucru este să indicați ce câmpuri să adunați, ca în exemplul următor:

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

    În codul precedent, câmpul Cost este evidențiat, iar fiecare element din acel câmp se adaugă la total.

  • average(): Această funcție este similară cu sum() în faptul că funcționează pe o listă de numere, dar cu două diferențe:

    • Se așteaptă ca datele să fie numere în virgulă mobilă, nu numere întregi.
    • Calculează o medie în loc de o sumă.

    Iată un exemplu:

    let numbers = [ 1.0; 2.5; 3.0 ]
    let avg = List.average numbers
    printfn "%f" avg // 2.166667
    
  • averageBy(): Cum ar fi sumBy(), averageBy() preia o funcție în care specificați ce valoare doriți. Iată un exemplu:

    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