Toimintojen suorittaminen luetteloille

Valmis

Kun tallennat useita kohteita luetteloon, suoritat usein toimintoja luettelon joko osittain tai kaikissa. Luettelomoduuli sisältää monia hyödyllisiä toimintoja, joiden avulla voit tehdä juuri niin.

Luettelomoduulifunktiot

Ominaisuuksien lisäksi on luettelomoduuli, joka on täynnä luettelossa toimivia funktioita. Funktiot voivat suorittaa yleisesti käytettyjä toimintoja, kuten etsimistä, suodatusta, lajittelua, matemaattisten operaatioiden suorittamista ja paljon muuta.

Iteraatio

Iteroidaksesi tarkoittaa, että voit käydä läpi luettelon jokaisen elementin aloituspisteestä päättymispisteeseen. Iteraation osalta on kaksi erityisen kiinnostavaa funktiota:

  • iter(): Tämän funktion avulla voit iteroida luettelon jokaisen kohteen seuraavassa esitetyllä tavalla:

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

    iter() funktiolla on funktio. Edellisessä koodissa annat anonyymin funktion käyttämällä fun-avainsanaa. Tällä funktiolla on parametri, joka edustaa nykyistä kohdetta iteroituna. Seuraava koodi vastaa seuraavan koodin kirjoittamista silmukalla:

    for i in cards do printfn "%i" i
    
  • map(): Tämä funktio muistuttaa iter(), mutta sen avulla voit muuntaa, mitä sinulla on. Tässä on esimerkki:

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

    Edellisessä koodissa Person-objektien luettelo muunnetaan merkkijonoluetteloksi.

Suodatin

filter()-funktio ottaa funktion myös parametriksi, mutta sen tarkoituksena on määrittää, mitä elementtejä säilytetään. Jos lausekkeen arvoksi tulee true, elementti säilytetään. Jos lauseke on false, elementti ei ole osa suodatettua luetteloa. Seuraavassa esimerkissä luettelo suodatetaan niin, että se säilyttää vain kohteet, joiden arvo on jaettavissa kahdella:

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

filteredList-luettelo sisältää nyt vain elementit, jotka palauttavat true, kun i % 2 = 0, joka on 2 ja 4, arvioimia.

Laji

Lajitteluluetteloita tehdään todennäköisesti usein. Seuraavassa on kolme funktiota, jotka saattavat olla hyödyllisiä luetteloiden lajittelemisen aikana:

  • sort()lajittelee nousevaan järjestykseen. Tässä on esimerkki:

    let list = [2; 1; 5; 3]
    let sortedList = List.sort list // 1 2 3 5 
    
  • sortBy(): Tämän funktion avulla ajatuksena on huomauttaa lajitteluavaimesta. Oletetaan, että sinulla on luettelo henkilöistä, ja jokaisessa tietueessa on kentät name ja age. Voit sitten huomauttaa lajitteluperusteena age, esimerkiksi . Tällä funktiolla on funktio, jossa osoitat avaimen. Toinen avain voi olla merkkijonon pituus, kuten tässä esimerkissä:

    let fruits = ["Banana"; "Apple"; "Pineapple"]
    let sortedFruits = List.sortBy (fun (fruit : string) -> fruit.Length) fruits // Apple, Banana, Pineapple
    
  • sortWith(): Tällä funktiolla voit antaa vertailufunktion, koska ei ehkä ole selvää, mikä useista kohteista tulee lajitella ennen muita kohteita. Tässä on esimerkkikoodi:

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

    Edellä oleva vertailufunktio compareCreatures() yrittää ensimmäistä kertaa vertailla kohdetta Level. Jos taso on yhtä suuri, se yrittää vertailla sitä käyttämällä Attack. Se palauttaa -1, jos jotakin pidetään pienempana, 1, jos se on suurempi, ja 0, jos se on yhtä suuri.

Haluat ehkä myös löytää tietyn elementin. Voit tehdä tämän valitsemalla seuraavista funktioista:

  • find(): Tämä funktio löytää ensimmäisen tiettyä ehtoa vastaavan elementin. Jos haluat käyttää find(), sinun on annettava funktio (predikaatti), joka ilmaisee, miten kohde etsitään. Tässä on esimerkki:

    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(). Tällä funktiolla on funktio (predikaatti), joka kertoo, miten arvo ja luettelo löytyvät tutkittavasta luettelosta. Se palauttaa asetuksen. Voit käyttää sitä näin:

    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
    

    Edellisessä koodissa lähetät arvon, jota verrataan luetteloosi. Jos se löydetään, se palauttaa Some. Jos sitä ei löydy, se palauttaa None.

  • tryFindIndex(). kuten tryFind(), tämä funktio palauttaa asetuksen, ja siihen tarvitaan funktio (predikaatti), joka antaa tulokseksi totuusarvon. Koodi voi näyttää tältä:

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

Aritmeettiset toiminnot

Matemaattisten operaatioiden suorittaminen luettelossa voi olla arvokasta. Luettelon ohjelmointirajapinnassa on monia funktioita, joista voi valita. Tässä on kolme hyödyllisintä funktiota:

  • sum(): käyttämällä tätä funktiota iteroidaan jokaiselle kohteelle luettelon kaikkien arvojen yhteen laskemiseksi. Voit käyttää sitä näin:

    let sum = List.sum [1 .. 5] // sum = 15 
    
  • sumBy(): Tämän funktion avulla ajatuksena on huomauttaa, miten arvot lasketaan yhteen. Yksi tapa tehdä se on huomauttaa, mitkä kentät lasketaan yhteen, kuten seuraavassa esimerkissä:

    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
    

    Edellisessä koodissa näytetään Cost -kenttä, ja jokainen kyseisen kentän kohde lisää summan.

  • average(): Tämä funktio muistuttaa sum(), koska se toimii lukuluettelossa, mutta sillä on kaksi eroa:

    • Se odottaa tietojen olevan liukulukuja, ei kokonaislukuja.
    • Se laskee keskiarvon summan asemesta.

    Tässä on esimerkki:

    let numbers = [ 1.0; 2.5; 3.0 ]
    let avg = List.average numbers
    printfn "%f" avg // 2.166667
    
  • averageBy(): kuten sumBy(), averageBy() määrittää haluamasi arvon funktiolla. Tässä on esimerkki:

    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