Home

F# Arrays: Finding an Item in an Array

   

Introduction

To let you find an item in an array, the Array class has a method named find. Its signature is:

List.find : ('T -> bool) -> 'T list -> 'T

This method takes two arguments. The first is a Boolean function that applies a condition to the values of the array that is the second argument. Here is an example:

open System
open System.Drawing
open System.Windows.Forms 

type Customer = {
    AccountNumber : string
    FirstName     : string
    LastName      : string }

and GasBill(billNbr, client : Customer, meterReading) =
    let bNbr = ref billNbr
    let cust = ref client
    let (rStart, rEnd) = meterReading

    member this.InvoiceNumber with get() = !bNbr and set(nbr) = bNbr := nbr
    member this.Customer with get() = !cust and set(nbr) = cust := nbr
    member this.MeterReadingStart with get() = rStart
    member this.MeterReadingEnd with get() = rEnd
    member this.Usage with get() = rEnd - rStart
    member this.TotalCCF with get() = this.Usage * 1.012
    member this.TotalTherms with get() = this.TotalCCF * 1.034

    member this.ServiceCharge with get() = 5.85
    member this.DistributionCharge with get() =
                                    let first100Therms = ref 0.00
                                    let above100Therms = ref 0.00

                                    if this.TotalTherms <= 100.00 then
                                        first100Therms := this.TotalTherms * 0.351869
                                        above100Therms := 0.00
                                    else
                                        first100Therms := 100.00 * 0.3518693
                                        above100Therms := (this.TotalTherms - 100.00) * 0.292748
                                    !first100Therms + !above100Therms
    member this.TotalDelivery with get() = this.ServiceCharge + this.DistributionCharge
                                    
    member this.MunicipalTax with get() = this.DistributionCharge * 0.86 / 100.00
    member this.StateTax with get() = this.DistributionCharge * 0.258 / 100.00
    member this.TotalInvoice with get() = this.TotalDelivery + this.MunicipalTax + this.StateTax
    new() = GasBill(0, { AccountNumber = ""; FirstName = ""; LastName = "" }, (0.00, 0.00))

let customers : Customer array = Array.zeroCreate 5

customers.[0] <- { AccountNumber = "807495"; FirstName = "Julius"; LastName = "Gluck" }
customers.[1] <- { AccountNumber = "928037"; FirstName = "Stephanie"; LastName = "Dugan" }
customers.[2] <- { AccountNumber = "279714"; FirstName = "William"; LastName = "Bamberg" }
customers.[3] <- { AccountNumber = "680513"; FirstName = "Kelly"; LastName = "Stewart" }
customers.[4] <- { AccountNumber = "479242"; FirstName = "Mark"; LastName = "Goddard" }

let mutable bills = [| new GasBill(); new GasBill(); new GasBill(); new GasBill(); new GasBill(); new GasBill(); new GasBill() |];

Array.set bills 0 (new GasBill(100001, customers.[1], ( 6527.00,  6739.00)))
Array.set bills 1 (new GasBill(100002, customers.[3], (12582.00, 12846.00)))
Array.set bills 2 (new GasBill(100003, customers.[4], ( 3019.00,  3102.00)))
Array.set bills 3 (new GasBill(100004, customers.[2], (27471.00, 27829.00)))
Array.set bills 4 (new GasBill(100005, customers.[0], (48731.00, 48825.00)))
Array.set bills 5 (new GasBill(100006, customers.[1], ( 6739.00,  6997.00)))
Array.set bills 6 (new GasBill(100007, customers.[4], ( 3102.00,  3218.00)))

Array.append bills [| new GasBill(100008, customers.[3], (12846.00, 128921.00)) |] |> ignore
Array.append bills [| new GasBill(100009, customers.[2], (27829.00, 28229.00)) |] |> ignore

let gasUtilityCompany : Form = new Form(MaximizeBox = false, Text = "Gas Utility company - Customers Invoices", ClientSize = new System.Drawing.Size(410, 490), StartPosition = FormStartPosition.CenterScreen)

let lvwInvoices : ListView = new ListView(GridLines = true, View = View.Details, FullRowSelect = true, Location = new Point(24, 21), Size = new System.Drawing.Size(365, 122))

let mutable colInvoice = lvwInvoices.Columns.Add("Invoice #", 60)
colInvoice <- lvwInvoices.Columns.Add("Customer", 65, HorizontalAlignment.Center)
colInvoice <- lvwInvoices.Columns.Add("Usage", 45, HorizontalAlignment.Right)
colInvoice <- lvwInvoices.Columns.Add("Delivery", 55, HorizontalAlignment.Right)
colInvoice <- lvwInvoices.Columns.Add("Taxes", 50, HorizontalAlignment.Right)
colInvoice <- lvwInvoices.Columns.Add("Amt Owed", 65, HorizontalAlignment.Right)

Array.iter (fun (bill : GasBill) -> 
    let lviInvoice = new ListViewItem(sprintf "%i" bill.InvoiceNumber)
    lviInvoice.SubItems.Add(sprintf "%s" bill.Customer.AccountNumber) |> ignore
    lviInvoice.SubItems.Add(sprintf "%0.0f" bill.TotalTherms) |> ignore
    lviInvoice.SubItems.Add(sprintf "%0.02f" bill.TotalDelivery) |> ignore
    lviInvoice.SubItems.Add(sprintf "%0.02f" (bill.MunicipalTax + bill.StateTax)) |> ignore
    lviInvoice.SubItems.Add(sprintf "%0.02f" bill.TotalInvoice) |> ignore
    lvwInvoices.Items.Add lviInvoice |> ignore) bills
gasUtilityCompany.Controls.Add lvwInvoices

gasUtilityCompany.Controls.Add(new Label(Location = new Point(20, 167), AutoSize = true, Text = "Account #:"))
let txtAccountNumber : TextBox = new TextBox(Location = new Point(98, 164), Width = 78)
gasUtilityCompany.Controls.Add txtAccountNumber

let txtCustomerName : TextBox = new TextBox(Location = new Point(184, 164), Width = 205)
gasUtilityCompany.Controls.Add txtCustomerName

let lblMeterReading = new Label(Location = new Point(20, 196), AutoSize = true)
lblMeterReading.Text <- "Meter Reading ______________"
gasUtilityCompany.Controls.Add lblMeterReading

let lblInvoiceDetails = new Label(Location = new Point(205, 196), AutoSize = true)
lblInvoiceDetails.Text <- "Invoice Details __________________"
gasUtilityCompany.Controls.Add lblInvoiceDetails

gasUtilityCompany.Controls.Add(new Label(Location = new Point(22, 229), AutoSize = true, Text = "Start:"))
let txtMeterReadingStart : TextBox = new TextBox(Location = new Point(100, 226), Width = 78, Text = "0.00", TextAlign = HorizontalAlignment.Right)
gasUtilityCompany.Controls.Add txtMeterReadingStart

gasUtilityCompany.Controls.Add(new Label(Location = new Point(205, 229), AutoSize = true, Text = "Service Delivery"))

gasUtilityCompany.Controls.Add(new Label(Location = new Point(22, 254), AutoSize = true, Text = "End:"))
let txtMeterReadingEnd : TextBox = new TextBox(Location = new Point(100, 252), Width = 78, Text = "0.00", TextAlign = HorizontalAlignment.Right)
gasUtilityCompany.Controls.Add txtMeterReadingEnd

gasUtilityCompany.Controls.Add(new Label(Location = new Point(205, 254), AutoSize = true, Text = "Service Charge:"))
let txtServiceCharge : TextBox = new TextBox(Location = new Point(325, 252), Width = 65, Text = "0.00", TextAlign = HorizontalAlignment.Right)
gasUtilityCompany.Controls.Add txtServiceCharge

gasUtilityCompany.Controls.Add(new Label(Location = new Point(22, 281), AutoSize = true, Text = "Difference:"))
let txtDifference : TextBox = new TextBox(Location = new Point(100, 278), Width = 78, Text = "0.00", TextAlign = HorizontalAlignment.Right)
gasUtilityCompany.Controls.Add txtDifference

gasUtilityCompany.Controls.Add(new Label(Location = new Point(205, 281), AutoSize = true, Text = "Distribution Charge:"))
let txtDistributionCharge : TextBox = new TextBox(Location = new Point(325, 278), Width = 65, Text = "0.00", TextAlign = HorizontalAlignment.Right)
gasUtilityCompany.Controls.Add txtDistributionCharge

gasUtilityCompany.Controls.Add(new Label(Location = new Point(22, 312), AutoSize = true, Text = "Conversion to CCF: * 1.0120"))

gasUtilityCompany.Controls.Add(new Label(Location = new Point(205, 312), AutoSize = true, Text = "Total Delivery:"))
let txtTotalDelivery : TextBox = new TextBox(Location = new Point(325, 306), Width = 65, Text = "0.00", TextAlign = HorizontalAlignment.Right)
gasUtilityCompany.Controls.Add txtTotalDelivery

gasUtilityCompany.Controls.Add(new Label(Location = new Point(22, 340), AutoSize = true, Text = "CCF Total:"))
let txtTotalCCF : TextBox = new TextBox(Location = new Point(100, 347), Width = 78, Text = "0.00", TextAlign = HorizontalAlignment.Right)
gasUtilityCompany.Controls.Add txtTotalCCF

let lblTaxes = new Label(Location = new Point(209, 344), AutoSize = true)
lblTaxes.Text <- "Taxes ________________________"
gasUtilityCompany.Controls.Add lblTaxes

gasUtilityCompany.Controls.Add(new Label(Location = new Point(22, 372), AutoSize = true, Text = "Conversion to Therms: * 1.034"))

gasUtilityCompany.Controls.Add(new Label(Location = new Point(205, 374), AutoSize = true, Text = "Municipal Tax (8.6%):"))
let txtMunicipalTax : TextBox = new TextBox(Location = new Point(325, 371), Width = 65, Text = "0.00", TextAlign = HorizontalAlignment.Right)
gasUtilityCompany.Controls.Add txtMunicipalTax

gasUtilityCompany.Controls.Add(new Label(Location = new Point(22, 400), AutoSize = true, Text = "Therms Total:"))
let txtTotalTherms : TextBox = new TextBox(Location = new Point(100, 397), Width = 78, Text = "0.00", TextAlign = HorizontalAlignment.Right)
gasUtilityCompany.Controls.Add txtTotalTherms

gasUtilityCompany.Controls.Add(new Label(Location = new Point(205, 400), AutoSize = true, Text = "State Tax (2.58%):"))
let txtStateTax : TextBox = new TextBox(Location = new Point(325, 397), Width = 65, Text = "0.00", TextAlign = HorizontalAlignment.Right)
gasUtilityCompany.Controls.Add txtStateTax

let lblLine = new Label(Location = new Point(22, 420), AutoSize = true)
lblLine.Text <- "____________________________________________________________"
gasUtilityCompany.Controls.Add lblLine

gasUtilityCompany.Controls.Add(new Label(Location = new Point(205, 452), AutoSize = true, Text = "Total Invoice:"))
let txtTotalInvoice : TextBox = new TextBox(Location = new Point(325, 449), Width = 65, Text = "0.00", TextAlign = HorizontalAlignment.Right)
gasUtilityCompany.Controls.Add txtTotalInvoice

let lvwInvoicesSelectedIndexChanged(e : ListViewItemSelectionChangedEventArgs) =
    let invoiceSelected = int (e.Item.SubItems.Item(0).Text)

    let bill = Array.find (fun (invoice : GasBill) -> invoice.InvoiceNumber = invoiceSelected) bills
    let client = Array.find (fun (cust : Customer) -> cust.AccountNumber = bill.Customer.AccountNumber) customers

    txtAccountNumber.Text <- client.AccountNumber
    txtCustomerName.Text <- client.LastName + ", " + client.FirstName

    txtMeterReadingStart.Text <- sprintf "%0.0f" bill.MeterReadingStart
    txtMeterReadingEnd.Text <- sprintf "%0.0f" bill.MeterReadingEnd
    txtDifference.Text <- sprintf "%0.0f" bill.Usage
    txtTotalCCF.Text <- sprintf "%0.0f" bill.TotalCCF
    txtTotalTherms.Text <- sprintf "%0.0f" bill.TotalTherms
    txtServiceCharge.Text <- sprintf "%0.02f" bill.ServiceCharge
    txtDistributionCharge.Text <- sprintf "%0.02f" bill.DistributionCharge 
    txtTotalDelivery.Text <- sprintf "%0.02f" bill.TotalDelivery
    txtMunicipalTax.Text <- sprintf "%0.02f" bill.MunicipalTax
    txtStateTax.Text <- sprintf "%0.02f" bill.StateTax
    txtTotalInvoice.Text <- sprintf "%0.02f" bill.TotalInvoice

lvwInvoices.ItemSelectionChanged.Add lvwInvoicesSelectedIndexChanged

let btnClose = new Button(Location = new Point(103, 446), Text = "Close")
let btnCloseClick e = gasUtilityCompany.Close()
btnClose.Click.Add btnCloseClick
gasUtilityCompany.Controls.Add btnClose

[<EntryPoint>]
let main argv =
    Application.Run gasUtilityCompany
    0

Here is an example of testing the program:

Finding an Item in an Array

Finding an Item in an Array

     
     

Home Copyright © 2012-2015, FunctionX Home