Foundations of Arrays

Introduction

An array is a list of values where:

Creating an Array

An array is created using the [| and the |] operators. You have many options. To create an array of specifically known values, the formula to follow is:

[| member-1; member-2; Member-n |]

With this formula, inside the operators, specify the value of each item. The items are separated by semicolons. Here is an example:

[| "James"; "Annette"; "Hughs"; "Daniel" "Martine" |]

The array members don't have to be on the same line; you can put them on different lines:

[|
"James";
"Annette";
"Hughs";
"Daniel"
"Martine"
|]

If you do this, you can omit the semicolon. Also, to make your code easy to read, you should indent the items (but this is not a requirement):

[|
    "James"
    "Annette"
    "Hughs"
    "Daniel"
    "Martine"
|]

If your array consists of consecutive ASCII characters, consecutive alphabetical letters, or incrementing numbers, you can specify its values as a range. In this case, inside the operators, the formula to follow is:

start-value .. end-value

Here is an example:

[| 'e' .. 'l' |]

If your array consists of consecutive numbers that follow a common skipping scheme, you can specify its values using a skip range. To do this, inside the operators, the formula to follow is:

Start .. Step .. End

Here is an example:

[| 0 .. 2 .. 20 |]

In the same way, if the array contains items whose letters or numbers will be based on a specific expression, you can use a for loop to create the value of each. To do that, inside the operators, the formula to follow is:

for variable-name in range -> body

Here is an example:

[| for number in 1 .. 10 -> number * number |]

An alternative to the -> operator is to use the do yield expression. Here is an example:

[| for number in 1 .. 10 do yield number * number * number |]

Naming an Array

To refer to an array as one, you can store it in a variable. This is done using the let keyword followed by a name for the variable, and assigned the array. Here are examples:

let names       = [| "James"; "Annette"; "Hughs"; "Daniel"; "Martine" |]
let letters     = [| 'e' .. 'l' |]
let evenNumbers = [| 0 .. 2 .. 20 |]
let squared     = [| for number in 1 .. 10 do yield number * number |]

Displaying an Array

To display an array and all its members in the printf() or the printfn() function, use %A. Here are examples:

printfn "Names:           %A" ( [| "James"; "Annette"; "Hughs"; "Daniel"; "Martine" |] );
printfn "Letters:         %A" ( [| 'e' .. 'l' |] )
printfn "Even Numbers:    %A" ( [| 0 .. 2 .. 20 |] )
printfn "Squared Numbers: %A" ( [| for number in 1 .. 10 -> number * number * number |] )

These would produce:

Names:           [|"James"; "Annette"; "Hughs"; "Daniel" "Martine"|]
Letters:         [|'e'; 'f'; 'g'; 'h'; 'i'; 'j'; 'k'; 'l'|]
Even Numbers:    [|0; 2; 4; 6; 8; 10; 12; 14; 16; 18; 20|]
Squared Numbers: [|1; 8; 27; 64; 125; 216; 343; 512; 729; 1000|]
Press any key to close this window . . .

In the same way, you can use the name of the variable that holds an array. Here are examples:

let names       = [| "James"; "Annette"; "Hughs"; "Daniel"; "Martine" |]
let letters     = [| 'e' .. 'l' |]
let evenNumbers = [| 0 .. 2 .. 20 |]
let squared     = [| for number in 1 .. 10 do yield number * number * number |]
 
printfn "Names:           %A" names;
printfn "Letters:         %A" letters;
printfn "Even Numbers:    %A" evenNumbers;
printfn "Squared Numbers: %A\n" squared;

The Data Type of an Array

When you create an array, the compiler infers the type of values the array contains. In some cases, you will want to use a type other than the one the compiler thinks you are using. In some other cases, you will want to explicitly indicate the type of values of the array members.

To specify the data type of an array, after the name of the variable, type : followed the data type and the array keyword. Here are examples:

let names : string array   = [| "James"; "Annette"; "Hughs"; "Daniel"; "Martine" |]
let letters : char array   = [| 'a' .. 'f' |]
let oddNumbers : int array = [| 1 .. 2 .. 21 |]
let squared : float array  = [| for number in 1.00 .. 5.00 do yield ((-1.00) ** (number + 1.00)) / (2.00 * number) |]
 
printfn "Names:           %A" names;
printfn "Letters:         %A" letters;
printfn "Odd Numbers:     %A" oddNumbers;
printfn "Squared Numbers: %A\n" squared;

This would produce:

Names:           [|"James"; "Annette"; "Hughs"; "Daniel"; "Martine"|]
Letters:         [|'a'; 'b'; 'c'; 'd'; 'e'; 'f'|]
Odd Numbers:     [|1; 3; 5; 7; 9; 11; 13; 15; 17; 19; 21|]
Squared Numbers: [|0.5; -0.25; 0.1666666667; -0.125; 0.1|]
 
Press any key to close this window . . .

If the members consist of complex values, they are considered strings. In this case, you can omit the data type or set it as string. Here is an example:

let series = [| for number in 1 .. 8 do yield (string (1.00 ** (float number + 1.00)) + "/" + string (2 * number)) |]
printfn "Series Array: %A\n" series;

This would produce:

Series Array: [|"1/2"; "1/4"; "1/6"; "1/8"; "1/10"; "1/12"; "1/14"; "1/16"|]
 
Press any key to close this window . . .

Accessing the Members of an Array

Accessing Each Item

To access each individual item in an array, you can use a for loop. The formula to follow is:

for identifier in array Or array-name do
   body

Since all items are of the same type, use the appropriate character in the placeholder of the printf() or the printfn() function. Here is an example:

for n in [| "James"; "Annette"; "Hughs"; "Daniel"; "Martine" |] do
    printfn "Name: %s" n;

This would produce:

Name: James
Name: Annette
Name: Hughs
Name: Daniel
Name: Martine
Press any key to close this window . . .

Accessing An Item by its Index

As mentioned in the begining, each member of an array occupies a specific position know as its index. The first item has an index of 0, the second has an index of 1, the third as an index of 2, and so on. To access an item, you apply the square brackets to the name of the array. The formula to go from the begining to the end of the array is:

for identifier = start to end do
   body

In the body of the loop, access each looping item using the following formula:

array-name.[identifier]

Based on the earlier description, if you have an array named courses and it has 6 items, to access the third, you would use courses.[4]. Here are examples:

let courses = [| "ASTR 100"; "WRTG 381"; "BEHS 220"; "PHIL 140"; "ACCT 302"; "MATH 241" |];
let cubedNumbers = [| for number in 1 .. 10 -> number * number * number |];
 
printfn "Course Code\tCredits";
for i = 0 to 5 do
    printfn "%s\t    3" courses.[i];
printfn "-----------------------------";
for i = 0 to 9 do
    printfn "Number: %d" cubedNumbers.[i];

This would produce:

Course Code     Credits
ASTR 100            3
WRTG 381            3
BEHS 220            3
PHIL 140            3
ACCT 302            3
MATH 241            3
-----------------------------
Number: 1
Number: 8
Number: 27
Number: 64
Number: 125
Number: 216
Number: 343
Number: 512
Number: 729
Number: 1000
Press any key to close this window . . .

Accessing the Members in a Range

You can consider that an array is a series of ranges of values, from the begining of the array to a certain item, from a certain item to another in a range, and from a certain item to the end. This means that, when it comes to ranges in the array, you have three options.

To access the range of items from the begining to a specific index, the formula to follow is:

array-name.[..Index]

Here is an example:

let courses = [| "WRTG 101";
                 "WRTG 102";
                 "WRTG 201";
                 "WRTG 288";
                 "WRTG 351";
                 "WRTG 381";
                 "WRTG 388";
                 "WRTG 390";
                 "WRTG 461" |];
 
printfn "All Courses =-----------------";
printfn "Course Code\tCredits";
for i = 0 to 7 do
    printfn "%s\t    3" courses.[i];
printfn "-----------------------------";
 
printfn "First Four Courses =---------";
printfn "Course Code\tCredits";
let first = courses.[ .. 3 ]
for n in first do
    printfn "%s\t    3" n;

This would produce:

All Courses =-----------------
Course Code     Credits
WRTG 101            3
WRTG 102            3
WRTG 201            3
WRTG 288            3
WRTG 351            3
WRTG 381            3
WRTG 388            3
WRTG 390            3
-----------------------------
First Four Courses =---------
Course Code     Credits
WRTG 101            3
WRTG 102            3
WRTG 201            3
WRTG 288            3
Press any key to close this window . . .

To access the items in a certain range, specify the starting index, two periods, and the ending index. The formula to follow is:

array-name.[StartIndex .. EndIndex]

Here are examples:

let courses = [| "WRTG 101";
                 "WRTG 102";
                 "WRTG 201";
                 "WRTG 288";
                 "WRTG 351";
                 "WRTG 381";
                 "WRTG 388";
                 "WRTG 390";
                 "WRTG 461" |];
 
printfn "Some Courses =---------";
printfn "Course Code\tCredits";
let second = courses.[ 2 .. 4 ]
for n in second do
    printfn "%s\t    3" n;

This would produce:

Some Courses =---------
Course Code     Credits
WRTG 201            3
WRTG 288            3
WRTG 351            3
Press any key to close this window . . .

To access some items at the end of the array, inside the [| and the |] operators, specify the starting index and add two periods. The formula to follow is:

array-name.[StartIndex .. ]

Here are examples:

let courses = [| "WRTG 101";
                 "WRTG 102";
                 "WRTG 201";
                 "WRTG 288";
                 "WRTG 351";
                 "WRTG 381";
                 "WRTG 388";
                 "WRTG 390";
                 "WRTG 461" |];
 
printfn "Last Courses =---------";
printfn "Course Code\tCredits";
for n in courses.[ 3 .. ] do
    printfn "%s\t    3" n;

This would produce:

Last Courses =---------
Course Code     Credits
WRTG 288            3
WRTG 351            3
WRTG 381            3
WRTG 388            3
WRTG 390            3
WRTG 461            3

The Values of Items in an Array

An Empty Array

An array is considered empty if it doesn't contain any value. To create such an array, specify its value as [||]. To store that array in a variable, assign [||] to the variable. Here is an example:

let timesWorked = [||]

Even though the array is empty, you can access it. Here is an example:

let timesWorked = [||]
 
printfn "Times Worked: %A" timesWorked

This would produce:

Times Worked: [||]
Press any key to close this window . . .

Remember that an array is a list whose values must be specified at creation time. The reason is that the compiler needs to know the number of items in the array, and that number cannot change (that's the actual definition of an array as it is used in programming languages; in reality, the .NET Framework, or rather its Array class, provides a mechanism to change the size of an array). Based on this, if you create an empty array, it remains empty; as a result, you cannot add items to it (in reality, based on the real definitions of an array, you cannot add a new item to an array, but you can change the value that an existing item holds).

Checking Whether an Array is Empty

We know how to create an empty array, by leaving [||] empty. To let you find out whether an array is empty, you can use the match operator with an option as [||]. When that option is valid, the array is empty. You can use the underscore for the other option that indicates that the array has at least one element. Here are examples:

let numbers = [||]
let names = [| "Frank"; "James"; "Joshua"; "Mary" |]
 
match numbers with
| [||] -> printfn "The array contains no element"
| _ -> printfn "Numbers: %A" numbers
 
match names with
| [||] -> printfn "There are no names in the array"
| _ -> printfn "Name: %A" names

This would produce:

The array contains no element
Name: [|"Frank"; "James"; "Joshua"; "Mary"|]
Press any key to close this window . . .

Setting the Values of Items

As mentioned already, when creating an array, you must provide the values of its items. Sometimes you don't have those values, maybe because they are not yet available. One solution is to provide sample values. The idea is to specify the number of items in the array. Here is an example:

let timesWorked = [| 0.00; 0.00; 0.00; 0.00; 0.00; 0.00; 0.00; |]
 
printfn "Times Worked: %A" timesWorked

This would produce:

Times Worked: [|0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0|]
Press any key to close this window . . .

Of course, the sample values depend on the type of values. Here is an example for string items:

let daysWorked = [| ""; ""; ""; ""; ""; ""; ""; |]

When you have done this, the compiler reserves a fixed area of the computer memory for the array and stores each item in the appropriate consecutive position. By definition, you cannot add new items to the array, but you can change the value stored in a certain position. To do this, access the item by its position using the .[] operator as we saw already. You can then assign the desired value using the mutable operator <-. Here are examples:

let timesWorked = [| 0.00; 0.00; 0.00; 0.00; 0.00; 0.00; 0.00; |]
let daysWorked = [| ""; ""; ""; ""; ""; ""; ""; |]
 
timesWorked.[0] <- 6.00
timesWorked.[1] <- 7.50
timesWorked.[2] <- 8.00
timesWorked.[3] <- 6.50
timesWorked.[4] <- 7.50
timesWorked.[5] <- 0.00
timesWorked.[6] <- 0.00
 
daysWorked.[0] <- "Monday"
daysWorked.[1] <- "Tuesday"
daysWorked.[2] <- "Wednesday"
daysWorked.[3] <- "Thursday"
daysWorked.[4] <- "Frisday"
daysWorked.[5] <- "Saturday"
daysWorked.[6] <- "Sunday"
 
printfn "Days Worked: "
for day in daysWorked do
    printfn "\t%s" day
 
printfn "Times Worked: %A" timesWorked

This would produce:

Days Worked:
        Monday
        Tuesday
        Wednesday
        Thursday
        Frisday
        Saturday
        Sunday
Times Worked: [|6.0; 7.5; 8.0; 6.5; 7.5; 0.0; 0.0|]
Press any key to close this window . . .

Arrays and Functions

Returning an Array

You can create a function that manipulates some values, produces an array, and returns it. You can then call the function to get its returned array and use it as you see fit. Here is an example:

let daysWorked() = 
    let daysWorked = [| ""; ""; ""; ""; ""; ""; ""; |]
 
    daysWorked.[0] <- "Monday   ";
    daysWorked.[1] <- "Tuesday  ";
    daysWorked.[2] <- "Wednesday";
    daysWorked.[3] <- "Thursday ";
    daysWorked.[4] <- "Frisday  ";
    daysWorked.[5] <- "Saturday ";
    daysWorked.[6] <- "Sunday   ";
 
    // Array returned
    daysWorked
 
let days = daysWorked();
 
printfn "====================================="
printfn "Day Worked\tTime Worked"
printfn "-------------------------------------"
for i = 0 to 6 do
    printfn "%s" days.[i];
printfn "====================================="

In the same way, you can pass one or more values to a function. The function can use the values to generate an array from its internal calculations. Here is an example:

let generateReciprocalInverses start finish =
    [| for n = start to finish - 1 do yield "-1/" + (string n) |] // Returned array
 
let inverses = generateReciprocalInverses 3 12
let mutable i = 3;
 
printfn "================================="
printfn "Receiprocal Inverses from 3 to 12"
printfn "------------------------"
printfn "      Reciprocal"
printfn "Nbr    Inverse"
printfn "---------------------------------"
for n in inverses do
    printfn "%i\t%s" i n
    i <- i + 1
printfn "================================="

This would produce:

========================
Inverses from 3 to 12
------------------------
      Reciprocal
Nbr    Inverse
------------------------
3       -1/3
4       -1/4
5       -1/5
6       -1/6
7       -1/7
8       -1/8
9       -1/9
10      -1/10
11      -1/11
========================
Press any key to close this window . . .

An Array as Parameter

An array can be passed as a parameter to a function. Consider the following example:

let showPayroll values =
    for time in values do
        printfn "Time Worked: %0.02F" time;

When calling the function, pass an array that holds the appropriate and desired values. Here is an example:

let timesWorked = [| 8.00; 8.50; 6.50; 7.50; 9.00; 0.00; 0.00; |];
 
let showPayroll values =
    for time in values do
        printfn "Time Worked: %0.02F" time;
 
showPayroll timesWorked;

This would produce:

Time Worked: 8.00
Time Worked: 8.50
Time Worked: 6.50
Time Worked: 7.50
Time Worked: 9.00
Time Worked: 0.00
Time Worked: 0.00
Press any key to close this window . . .

In the samy way, you can pass more than one array to a function.

Remember that F# is an inferred language. This means that when passing an array or many arrays to a function, the compiler may not know the type of value an array parameter holds. The parameter can be anything. If the compiler has any difficult figuring out the types of parameter, it would produce an error. Therefore, it is recommended that it indicate the type of the parameter. Here are examples:

let timesWorked = [| 0.00; 0.00; 0.00; 0.00; 0.00; 0.00; 0.00; |]
let daysWorked = [| ""; ""; ""; ""; ""; ""; ""; |]
 
timesWorked.[0] <- 6.00
timesWorked.[1] <- 7.50
timesWorked.[2] <- 8.00
timesWorked.[3] <- 6.50
timesWorked.[4] <- 7.50
timesWorked.[5] <- 0.00
timesWorked.[6] <- 0.00
 
daysWorked.[0] <- "Monday   ";
daysWorked.[1] <- "Tuesday  ";
daysWorked.[2] <- "Wednesday";
daysWorked.[3] <- "Thursday ";
daysWorked.[4] <- "Frisday  ";
daysWorked.[5] <- "Saturday ";
daysWorked.[6] <- "Sunday   "
 
let showPayroll (days : string array) (values : float array) =
    printfn "============================"
    printfn "Day Worked\tTime Worked"
    printfn "----------------------------"
    for i = 0 to 6 do
        printfn "%s\t%0.02F" days.[i] values.[i];
    printfn "============================"
 
showPayroll daysWorked timesWorked;

This would produce:

============================
Day Worked      Time Worked
----------------------------
Monday          6.00
Tuesday         7.50
Wednesday       8.00
Thursday        6.50
Frisday         7.50
Saturday        0.00
Sunday          0.00
============================
Press any key to close this window . . .

A function can do more than simply displaying the values of an array it gets as parameter. It can use the values of that array, perform some calculations, and simply return a new value. A function can also get an array as parameter and return an array.

Arrays and Records

An Array of Records

The items of an array can come from a record. Of course, you must have a record. You can create various objects and add each to an array. Here is an example:

type Employee = {
    EmployeeNumber : string
    FirstName      : string
    LastName       : string
    HourlySalary   : double }
 
let empl80223840 = { EmployeeNumber = "8022-3840"; FirstName = "Mark";  LastName = "Plant";  HourlySalary = 24.55 }
let empl58402497 = { EmployeeNumber = "5840-2497"; FirstName = "Carol"; LastName = "Mylans"; HourlySalary = 16.25 }
let empl20817008 = { EmployeeNumber = "2081-7008"; FirstName = "Maria"; LastName = "Pappas"; HourlySalary = 22.75 }
 
let employees = [| empl80223840; empl58402497; empl20817008 |]

A better alternative is to create each object directly in the array. After creating the array, you can access the members of the record using the period operator. Here is an example:

type Employee = {
    EmployeeNumber : string
    FirstName      : string
    LastName       : string
    HourlySalary   : double }
 
let employees = [| { EmployeeNumber = "8022-3840"; FirstName = "Mark";  LastName = "Plant";  HourlySalary = 24.55 };
                   { EmployeeNumber = "5840-2497"; FirstName = "Carol"; LastName = "Mylans"; HourlySalary = 16.25 };
                   { EmployeeNumber = "2081-7008"; FirstName = "Maria"; LastName = "Pappas"; HourlySalary = 22.75 }; |]
 
printfn "Employees Records _______"
for empl in employees do
    printfn "=-=-=-=-=-=-=-=-=-=-=-=-="
    printfn "Employee Record"
    printfn "-------------------------"
    printfn "Employee #:     %s" empl.EmployeeNumber
    printfn "First Name:     %s" empl.FirstName
    printfn "Last Name:      %s" empl.LastName
    printfn "Hourly Salary: %.02F" empl.HourlySalary
printfn "=============================================="

This would produce:

Employees Records _______
=-=-=-=-=-=-=-=-=-=-=-=-=
Employee Record
-------------------------
Employee #:     8022-3840
First Name:     Mark
Last Name:      Plant
Hourly Salary: 24.55
=-=-=-=-=-=-=-=-=-=-=-=-=
Employee Record
-------------------------
Employee #:     5840-2497
First Name:     Carol
Last Name:      Mylans
Hourly Salary: 16.25
=-=-=-=-=-=-=-=-=-=-=-=-=
Employee Record
-------------------------
Employee #:     2081-7008
First Name:     Maria
Last Name:      Pappas
Hourly Salary: 22.75
==============================================
Press any key to close this window . . .

An Array as a Member of a Record

A member of a record can be an array. When creating the member, specify its type followed by the array keyword. Here is an example:

type RoadSystem = {
    RoadName : string
    Distance : float
    Location : string
    Intersections : string array }

In the same way, you can create as many array members as you want. When creating an object, specify the value of the member as an array. Outside the object, you can display the array member using %A in the placeholder of the printf() or the printfn() function. Here is an example:

type RoadType =
    | Court
    | Street
    | Road
    | Avenue
    | Boulevard
    | StateRoad
    | StateHighway
    | Interstate
    | Unknown
    
type RoadSystem = {
    RoadName : string
    Category : RoadType
    Distance : float
    Location : string
    Intersections : string array }
 
let MD410 = {
        RoadName = "MD 410";
        Category = RoadType.Road;
        Distance = 13.92; // mi => 22.40 km
        Location = "From East Bethesda to Pennsy Drive in Landover Hills";
        Intersections = [| "MD 355"; "MD 187"; "Maple Ave"; "MD 185"; "Colesville Rd" |] }
    
printfn "Road System Database"
printfn "=-----------------------------------------------------------------------------="
printfn "Road Name:       %s" MD410.RoadName
printfn "Category:        %A" MD410.Category
printfn "Distance:        %0.2f miles" MD410.Distance
printfn "Location:        %s" MD410.Location
printfn "Intersects With: %A\n" MD410.Intersections
printfn "=-----------------------------------------------------------------------------="

This would produce:

Road System Database
=-----------------------------------------------------------------------------=
Road Name:       MD 410
Category:        Road
Distance:        13.92 miles
Location:        From East Bethesda to Pennsy Drive in Landover Hills
Intersects With: [|"MD 355"; "MD 187"; "Maple Ave"; "MD 185"; "Colesville Rd"|]
=-----------------------------------------------------------------------------=
Press any key to close this window . . .

Arrays and Classes

An Array of Objects

The members of an array can be of any type, including objects of a class or structure. You can first create each object and add it to an array variable. Here is an example:

type StoreItem(number, make, category, subcategory, name, size, price, discrate) =
    let mutable nbr = number
    let mutable mk = make
    let mutable cat = category
    let mutable sub = subcategory
    let mutable nm = name
    let mutable sz = size
    let mutable prc = price
    let mutable rate = discrate
 
    member this.ItemNumber   with get() = nbr  and set(value) = nbr  <- value;
    member this.Manufacturer with get() = mk   and set(value) = mk   <- value;
    member this.Category     with get() = cat  and set(value) = cat  <- value;
    member this.SubCategory  with get() = sub  and set(value) = sub  <- value;
    member this.ItemName     with get() = nm   and set(value) = nm   <- value;
    member this.ItemSize     with get() = sz   and set(value) = sz   <- value;
    member this.UnitPrice    with get() = prc  and set(value) = prc  <- value;
    member this.DiscountRate with get() = rate and set(value) = rate <- value;
    member this.GetDiscountAmount() = this.UnitPrice * this.DiscountRate / 100.00;
    member this.MarkedPrice() = this.UnitPrice - this.DiscountRate;
    new(number, make, category, subcategory, name, size, price) = StoreItem(number, make, category, subcategory, name, size, price, 0.00)
 
let si1 = StoreItem("441180", "Ralph Lauren", "Girls", "Shirts", "Girls 2-6X Short-Sleeved Mesh Polo Shirt", "3/3T", 34.95);
let si2 = StoreItem("292915", "Kenneth Cole", "Women", "Dresses", "Three-Quarter Sleeved Dress", "L", 145.50, 20.00);
let si3 = StoreItem("479160", "Polo Ralph Lauren", "Men", "Pants", "Classic Straight-Leg Jeans", "33W - 32L", 84.85); 
 
let storeItems = [| si1; si2; si3;|];

A better alternative is to create each object in its placeholder in the array. Here is an example:

let storeItems = [| StoreItem("441180", "Ralph Lauren", "Girls", "Shirts", "Girls 2-6X Short-Sleeved Mesh Polo Shirt", "3/3T", 34.95);
                    StoreItem("292915", "Kenneth Cole", "Women", "Dresses", "Three-Quarter Sleeved Dress", "L", 145.50, 20.00);
                    StoreItem("479160", "Polo Ralph Lauren", "Men", "Pants", "Classic Straight-Leg Jeans", "33W - 32L", 84.85);
                 |];

To access a member of the array, you can use a for loop. Then, from the name of the looping identifier, use the period operator to access a member of the class. Here are examples:

type StoreItem(number, make, category, subcategory, name, size, price, discrate) =
    let mutable nbr = number
    let mutable mk = make
    let mutable cat = category
    let mutable sub = subcategory
    let mutable nm = name
    let mutable sz = size
    let mutable prc = price
    let mutable rate = discrate
 
    member this.ItemNumber   with get() = nbr  and set(value) = nbr  <- value;
    member this.Manufacturer with get() = mk   and set(value) = mk   <- value;
    member this.Category     with get() = cat  and set(value) = cat  <- value;
    member this.SubCategory  with get() = sub  and set(value) = sub  <- value;
    member this.ItemName     with get() = nm   and set(value) = nm   <- value;
    member this.ItemSize     with get() = sz   and set(value) = sz   <- value;
    member this.UnitPrice    with get() = prc  and set(value) = prc  <- value;
    member this.DiscountRate with get() = rate and set(value) = rate <- value;
    member this.GetDiscountAmount() = this.UnitPrice * this.DiscountRate / 100.00;
    member this.MarkedPrice() = this.UnitPrice - this.GetDiscountAmount();
    new(number, make, category, subcategory, name, size, price) = StoreItem(number, make, category, subcategory, name, size, price, 0.00) 
 
let storeItems = [| StoreItem("441180", "Ralph Lauren", "Girls", "Shirts", "Girls 2-6X Short-Sleeved Mesh Polo Shirt", "3/3T", 34.95);
                    StoreItem("292915", "Kenneth Cole", "Women", "Dresses", "Three-Quarter Sleeved Dress", "L", 145.50, 20.00);
                    StoreItem("479160", "Polo Ralph Lauren", "Men", "Pants", "Classic Straight-Leg Jeans", "33W - 32L", 84.85);
                    StoreItem("561150", "Kenneth Cole", "Women", "Dresses", "Three-Quarter Sleeved Dress", "XS", 145.50, 20.00);
                    StoreItem("689771", "Calvin Klein", "Men", "Pants", "Straight Leg Jean in Black Wash", "38/30", 45.00);
                    StoreItem("570810", "Nautica", "Boys", "Sweaters", "Boys 2-7 Cashmere Cable V-neck Sweater", "2T/3T", 145.00);
                 |];
 
printfn "________________ Store Items _______________________________"
printfn "============================================================"
for storeItem in storeItems do
    printfn "Item #:          %s" storeItem.ItemNumber;
    printfn "Manufacturer:    %s" storeItem.Manufacturer;
    printfn "Category:        %s" storeItem.Category;
    printfn "Sub-Category:    %s" storeItem.SubCategory;
    printfn "Item Name:       %s" storeItem.ItemName;
    printfn "Item Size:       %s" storeItem.ItemSize;
    printfn "Unit Price:      %0.02f" storeItem.UnitPrice;
    printfn "Discount Rate:   %0.0f%s" storeItem.DiscountRate "%";
    printfn "Discount Amount: %0.02f" (storeItem.GetDiscountAmount());
    printfn "Marked Price:    %0.02f" (storeItem.MarkedPrice());
    printfn "------------------------------------------------------------"

This would produce:

________________ Store Items _______________________________
============================================================
Item #:          441180
Manufacturer:    Ralph Lauren
Category:        Girls
Sub-Category:    Shirts
Item Name:       Girls 2-6X Short-Sleeved Mesh Polo Shirt
Item Size:       3/3T
Unit Price:      34.95
Discount Rate:   0%
Discount Amount: 0.00
Marked Price:    34.95
------------------------------------------------------------
Item #:          292915
Manufacturer:    Kenneth Cole
Category:        Women
Sub-Category:    Dresses
Item Name:       Three-Quarter Sleeved Dress
Item Size:       L
Unit Price:      145.50
Discount Rate:   20%
Discount Amount: 29.10
Marked Price:    116.40
------------------------------------------------------------
Item #:          479160
Manufacturer:    Polo Ralph Lauren
Category:        Men
Sub-Category:    Pants
Item Name:       Classic Straight-Leg Jeans
Item Size:       33W - 32L
Unit Price:      84.85
Discount Rate:   0%
Discount Amount: 0.00
Marked Price:    84.85
------------------------------------------------------------
Item #:          561150
Manufacturer:    Kenneth Cole
Category:        Women
Sub-Category:    Dresses
Item Name:       Three-Quarter Sleeved Dress
Item Size:       XS
Unit Price:      145.50
Discount Rate:   20%
Discount Amount: 29.10
Marked Price:    116.40
------------------------------------------------------------
Item #:          689771
Manufacturer:    Calvin Klein
Category:        Men
Sub-Category:    Pants
Item Name:       Straight Leg Jean in Black Wash
Item Size:       38/30
Unit Price:      45.00
Discount Rate:   0%
Discount Amount: 0.00
Marked Price:    45.00
------------------------------------------------------------
Item #:          570810
Manufacturer:    Nautica
Category:        Boys
Sub-Category:    Sweaters
Item Name:       Boys 2-7 Cashmere Cable V-neck Sweater
Item Size:       2T/3T
Unit Price:      145.00
Discount Rate:   0%
Discount Amount: 0.00
Marked Price:    145.00
------------------------------------------------------------
Press any key to close this window . . .

Arrays and Properties of a Class

We already know how to pass an array as parameter. This means that an array can be passed to the constructor of a class. On the other hand, a property of a class can be an array. In fact, you can create a read-only property that would only produce an array that clients of the class can use. Otherwise, you can create a read-write property that gets its value as array from the outside and makes its array value available to the outside world.

Normally, when creating a read-write property that would use an array, you simply create a regular property. Here is an example:

type PayrollPreparation(number, times) =
    let mutable nbr = number;
    let mutable tms = times;
    member this.EmployeeeNumber with get() = nbr and set(value) = nbr <- value;
    member this.TimesWorked with get() = tms and set(value) = tms <- value;

It is when you specify the value of the property that you provide the array. Once this is done, when using the property outside the class, treat it as an array. Here is an example:

type Employee = {
    EmployeeNumber : string
    FirstName      : string
    LastName       : string
    HourlySalary   : double }
 
let employees = [| { EmployeeNumber = "8022-3840"; FirstName = "Mark";  LastName = "Plant";  HourlySalary = 24.55 };
                   { EmployeeNumber = "5840-2497"; FirstName = "Carol"; LastName = "Mylans"; HourlySalary = 16.25 };
                   { EmployeeNumber = "2081-7008"; FirstName = "Maria"; LastName = "Pappas"; HourlySalary = 22.75 }; |]
 
type PayrollPreparation(number, times) =
    let mutable nbr = number;
    let mutable tms = times;
    member this.EmployeeeNumber with get() = nbr and set(value) = nbr <- value;
    member this.TimesWorked with get() = tms and set(value) = tms <- value;
    member this.CalculateTotalTime() =
        let mutable sum = 0.00
        for t in tms do sum <- sum + t
        sum
    member this.CalculateWeeklySalary() =
        let mutable salary = 0.00;
        for empl in employees do
            if empl.EmployeeNumber = nbr then salary <- empl.HourlySalary
        this.CalculateTotalTime() * salary
 
let pp = PayrollPreparation("5840-2497", [| 6.0; 7.5; 8.0; 6.5; 7.5; 0.0; 0.0 |]);
 
printfn "======================================================"
printfn "Employee Payroll"
printfn "------------------------------------------------------"
printfn "Employee #:     %s" pp.EmployeeeNumber;
printf "Full Name:      "
do
    for empl in employees do
        if empl.EmployeeNumber = pp.EmployeeeNumber then printfn "%s, %s" empl.LastName empl.FirstName;
printf "Hourly Salary:  "
do
    for empl in employees do
        if empl.EmployeeNumber = pp.EmployeeeNumber then printfn "%.02F" empl.HourlySalary;
printfn "Times Worked:   %A:" pp.TimesWorked;
printfn "Weekly Time:    %.02F" (pp.CalculateTotalTime());
printfn "Weekly Salary:  %0.02f" (pp.CalculateWeeklySalary());
printfn "======================================================";

This would produce:

======================================================
Employee Payroll
------------------------------------------------------
Employee #:     5840-2497
Full Name:      Mylans, Carol
Hourly Salary:  16.25
Times Worked:   [|6.0; 7.5; 8.0; 6.5; 7.5; 0.0; 0.0|]:
Weekly Time:    35.50
Weekly Salary:  576.88
======================================================
Press any key to close this window . . .

Arrays and Methods of a Class

Like a regular function in a module, a method of a class can use an array in many ways. For example, a method can receive an array as parameter. We saw this for a constructor. A method can also return an array. When accessing the method outside the class, remember that it returns an array. This means that you can apply the operations of arrays on the call to that method. Here is an example:

type Employee = {
    EmployeeNumber : string
    FirstName      : string
    LastName       : string
    HourlySalary   : double }
 
let employees = [| { EmployeeNumber = "8022-3840"; FirstName = "Mark";  LastName = "Plant";  HourlySalary = 24.55 };
                   { EmployeeNumber = "5840-2497"; FirstName = "Carol"; LastName = "Mylans"; HourlySalary = 16.25 };
                   { EmployeeNumber = "2081-7008"; FirstName = "Maria"; LastName = "Pappas"; HourlySalary = 22.75 }; |]
 
type PayrollPreparation(number, times) =
    let mutable nbr = number;
    let mutable tms = times;
    member this.EmployeeeNumber with get() = nbr and set(value) = nbr <- value;
    member this.TimesWorked with get() = tms and set(value) = tms <- value;
    member this.PaySummary(hourlySalary) : float array =
        let mutable regularTime = 0.00
        let mutable overtime = 0.00
        let mutable regularAmount = 0.00
        let mutable overtimeSalary = 0.00
        let mutable totalWeekTime = 0.00
        let mutable overtimeAmount = 0.00
        
        for t in tms do totalWeekTime <- totalWeekTime + t
        overtimeSalary <- hourlySalary * 1.5
 
        // If the employee worked under 40 hours, there is no overtime
        if totalWeekTime < 40. then
            regularTime <- totalWeekTime
            regularAmount <- hourlySalary * regularTime
            //overtime <- 0.00
            //overtimeAmount <- 0.00
        // If the employee worked over 40 hours, calculate the overtime
        elif totalWeekTime >= 40. then
            regularTime <- 40.
            regularAmount <- hourlySalary * 40.
            overtime <- totalWeekTime - 40.
            overtimeAmount <- overtime * overtimeSalary
        [| regularTime; overtime; regularAmount; overtimeAmount; regularAmount + overtimeAmount |]
 
let pp = PayrollPreparation("5840-2497", [| 6.0; 7.5; 8.0; 6.5; 7.5; 0.0; 0.0 |]);
//let pp = PayrollPreparation("8022-3840", [| 8.50; 9.50; 10.00; 8.50; 9.50; 0.0; 0.0 |]);
let mutable salary = 0.00
 
do
    for empl in employees do
        if empl.EmployeeNumber = pp.EmployeeeNumber then salary <- empl.HourlySalary;
printfn "======================================"
printfn "Employee Payroll"
printfn "--------------------------------------"
printfn "Employee #:\t\t\t%s" pp.EmployeeeNumber;
printf "Full Name:\t\t\t"
do
    for empl in employees do
        if empl.EmployeeNumber = pp.EmployeeeNumber then printfn "%s, %s" empl.LastName empl.FirstName;
printfn "Hourly Salary:\t\t%.02F" salary;
printfn "Pay Summary___________________________"
for i = 0 to 4 do
    printfn "%s\t%0.02f" [| "Regular Time:   ";
                            "Overtime:       ";
                            "Regular Amount: ";
                            "Overtime Salary:";
                            "Net Pay:        " |].[i]
                           (pp.PaySummary(salary)).[i]
    printfn "--------------------------------------"

This would produce:

======================================
Employee Payroll
--------------------------------------
Employee #:			5840-2497
Full Name:			Mylans, Carol
Hourly Salary:		16.25
Pay Summary___________________________
Regular Time:   	35.50
--------------------------------------
Overtime:       	0.00
--------------------------------------
Regular Amount: 	576.88
--------------------------------------
Overtime Salary:	0.00
--------------------------------------
Net Pay:        	576.88
--------------------------------------

Notice that the method could have been written as follows (it may be long to read but it produces the same result):

type PayrollPreparation(number, times) =
    let mutable nbr = number;
    let mutable tms = times;
    member this.EmployeeeNumber with get() = nbr and set(value) = nbr <- value;
    member this.TimesWorked with get() = tms and set(value) = tms <- value;
    member this.PaySummary(hourlySalary) : float array =
        let mutable totalWeekTime = 0.00
                  
        for t in tms do totalWeekTime <- totalWeekTime + t
                                                                                            
        // If the employee worked under 40 hours, there is no overtime
        if totalWeekTime < 40. then
            [| totalWeekTime; 0.00; hourlySalary * totalWeekTime; 0.00; hourlySalary * totalWeekTime |]
        else // if totalWeekTime >= 40. then
            [| 40.00; totalWeekTime - 40.00; hourlySalary * 40.00; (totalWeekTime - 40.00) * (hourlySalary * 1.50); hourlySalary * 40.00 + ((totalWeekTime - 40.00) * (hourlySalary * 1.50)) |]

Characteristics of Arrays

Introduction

The F# language higly supports arrays. It provides many mechanisms to perform various types of operations. Besides the regular core operations of the language, the language's own library is equipped with a namespace named Microsoft.FSharp.Collections in which exists a module named Array(https://github.com/dotnet/fsharp/blob/main/src/FSharp.Core/array.fs).

An Empty Array

In some cases, if you are not ready to specify the values when creating the array, you can create it empty. To do this, specify the value of the array as [||]. Here is an example:

let timesWorked = [||];
 
printfn "Times Worked: %A" timesWorked;

This would produce:

Times Worked: [||]
Press any key to close this window . . .

As an alternative, to let you create an empty array, the Array module provides a function named empty. Its signature is:

Array.empty<'T> :  'T []

Here is an example of using it:

let timesWorked = Array.empty;
 
printfn "Times Worked: %A" timesWorked;

To let you find out whether an array is empty, the Array module provides a function named isEmpty. Its signature is:

Array.isEmpty : 'T [] -> bool

The Length of an Array

The length of an array is the number of items it contains. To let you get this information, the Array module is equipped with a property named Length. Here is an example of using it:

type Employee = {
    EmployeeNumber : string
    FirstName      : string
    LastName       : string
    HourlySalary   : double }
 
let employees = [| { EmployeeNumber = "8022-3840"; FirstName = "Mark";  LastName = "Plant";  HourlySalary = 24.55 };
                   { EmployeeNumber = "5840-2497"; FirstName = "Carol"; LastName = "Mylans"; HourlySalary = 16.25 };
                   { EmployeeNumber = "2081-7008"; FirstName = "Maria"; LastName = "Pappas"; HourlySalary = 22.75 }; |]
 
type PayrollPreparation(number, times) =
    let mutable nbr = number;
    let mutable tms = times;
    member this.EmployeeeNumber with get() = nbr and set(value) = nbr <- value;
    member this.TimesWorked with get() = tms and set(value) = tms <- value;
    member this.PaySummary(hourlySalary) : float array =
        let mutable regularTime = 0.00
        let mutable overtime = 0.00
        let mutable regularAmount = 0.00
        let mutable overtimeSalary = 0.00
        let mutable totalWeekTime = 0.00
        let mutable overtimeAmount = 0.00
        
        for t in tms do totalWeekTime <- totalWeekTime + t
        overtimeSalary <- hourlySalary * 1.5
 
        // If the employee worked under 40 hours, there is no overtime
        if totalWeekTime < 40. then
            regularTime <- totalWeekTime
            regularAmount <- hourlySalary * regularTime
            //overtime <- 0.00
            //overtimeAmount <- 0.00
        // If the employee worked over 40 hours, calculate the overtime
        elif totalWeekTime >= 40. then
            regularTime <- 40.
            regularAmount <- hourlySalary * 40.
            overtime <- totalWeekTime - 40.
            overtimeAmount <- overtime * overtimeSalary
        [| regularTime; overtime; regularAmount; overtimeAmount; regularAmount + overtimeAmount |]
 
    member this.CalculateTotalTime() =
        let mutable sum = 0.00
        for t in tms do sum <- sum + t
        sum
    member this.CalculateWeeklySalary() =
        let mutable salary = 0.00;
        for empl in employees do
            if empl.EmployeeNumber = nbr then salary <- empl.HourlySalary
        this.CalculateTotalTime() * salary
 
let pp = PayrollPreparation("5840-2497", [| 6.0; 7.5; 8.0; 6.5; 7.5; 0.0; 0.0 |]);
//let pp = PayrollPreparation("8022-3840", [| 8.50; 9.50; 10.00; 8.50; 9.50; 0.0; 0.0 |]);
let mutable salary = 0.00
 
do
    for empl in employees do
        if empl.EmployeeNumber = pp.EmployeeeNumber then salary <- empl.HourlySalary;
printfn "======================================"
printfn "Employee Payroll"
printfn "--------------------------------------"
printfn "Employee #:\t\t\t%s" pp.EmployeeeNumber;
printf "Full Name:\t\t\t"
do
    for empl in employees do
        if empl.EmployeeNumber = pp.EmployeeeNumber then printfn "%s, %s" empl.LastName empl.FirstName;
printfn "Hourly Salary:\t\t%.02F" salary;
printfn "Pay Summary___________________________"
for i = 0 to (pp.PaySummary(salary)).Length - 1 do
    printfn "%s\t%0.02f" [| "Regular Time:   ";
                            "Overtime:       ";
                            "Regular Amount: ";
                            "Overtime Salary:";
                            "Net Pay:        " |].[i]
                           (pp.PaySummary(salary)).[i]
    printfn "--------------------------------------"

As an alternative, the Array module is equipped with a function named length. The function takes one argument as the array whose number of items must be found.

Techniques of Creating Arrays

Creating an Array

We know that there are various techniques to create an array, and when creating an array, you should provide the original values of the array. One way to do this is is to initialize the array with the values of your choice. To support this, the Array module is equipped with a method named create. Its signature is:

Array.create : int -> 'T -> 'T []

This method takes two arguments. The first is the number of items the array will need. The second argument is the default value for each item.

Creating an Array With Zero Values

If you create an empty array, it remains empty and you cannot add values to it. That's why, when creating an array, you should provide the desired values. If you don't have those values, you can still create an array, specify its number of items, but specify each item as 0. To support this operation, the Array module is equipped with a method named zeroCreate. Its signature is:

Array.zeroCreate : int -> 'T []

This method takes one argument as the number of items in the array. Each item receives a value of 0. Here is an example of calling it:

let times : float array = Array.zeroCreate 5;

printfn "Times Worked: %A" times;

This would produce:

Times Worked: [|0.0; 0.0; 0.0; 0.0; 0.0|]
Press any key to close this window . . .

Initialyzing an Array

Introduction

After creating the array, you can specify the values of its members or you can change them. This can be done by accessing an item using the period operator and assigning a value using the -> operator. Here are exampes:

let times : float array = Array.zeroCreate 7;
 
times.[0] <- 8.00
times.[1] <- 8.50
times.[2] <- 6.00
times.[3] <- 9.00
times.[4] <- 7.50
times.[5] <- 9.00
times.[6] <- 7.50
 
for time in times do
    printfn "Time Worked: %0.02F" time;

This would produce:

Time Worked: 8.00
Time Worked: 8.50
Time Worked: 6.00
Time Worked: 9.00
Time Worked: 7.50
Time Worked: 9.00
Time Worked: 7.50
Press any key to close this window . . .

If the members of the array are objects, you can access each item by its index and assign an object-value to it. Here are examples:

type OccupancyStatus =
| Other       = 0
| Available   = 1
| Occupied    = 2
| NeedsRepair = 3
 
type Apartment = {
    UnitNumber      : string
    Bedrooms        : int
    Bathrooms       : float
    SecurityDeposit : int
    MonthlyRate     : int
    Status          : OccupancyStatus }
 
let apartments = Array.create 5 { UnitNumber = "101"; Bedrooms = 2; Bathrooms = 2.00; SecurityDeposit = 650; MonthlyRate = 1150; Status = OccupancyStatus.Available };
 
apartments.[1] <- { UnitNumber = "102"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit = 500; MonthlyRate =  950; Status = OccupancyStatus.NeedsRepair }
apartments.[2] <- { UnitNumber = "103"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit = 500; MonthlyRate =  925; Status = OccupancyStatus.Available   }
apartments.[3] <- { UnitNumber = "104"; Bedrooms = 3; Bathrooms = 2.00; SecurityDeposit = 850; MonthlyRate = 1350; Status = OccupancyStatus.Occupied    }
apartments.[4] <- { UnitNumber = "105"; Bedrooms = 2; Bathrooms = 1.00; SecurityDeposit = 550; MonthlyRate = 1150; Status = OccupancyStatus.Available   }

Setting the Values of an Array

To allow you to specify or change the value of an element of an array, the Array module provides a function named set. Its signature is:

Array.set : 'T [] -> int -> 'T -> unit

This function takes three arguments. The first is the array with elements. The second argument is the index of the element whose value you want to specify. The last argument is the value to set. Here is an example that sets the values of the second and the fourth members of the array:

type StoreItem(number, make, category, subcategory, name, size, price, discrate) =
    let mutable nbr = number
    let mutable mk = make
    let mutable cat = category
    let mutable sub = subcategory
    let mutable nm = name
    let mutable sz = size
    let mutable prc = price
    let mutable rate = discrate
 
    member this.ItemNumber   with get() = nbr  and set(value) = nbr  <- value;
    member this.Manufacturer with get() = mk   and set(value) = mk   <- value;
    member this.Category     with get() = cat  and set(value) = cat  <- value;
    member this.SubCategory  with get() = sub  and set(value) = sub  <- value;
    member this.ItemName     with get() = nm   and set(value) = nm   <- value;
    member this.ItemSize     with get() = sz   and set(value) = sz   <- value;
    member this.UnitPrice    with get() = prc  and set(value) = prc  <- value;
    member this.DiscountRate with get() = rate and set(value) = rate <- value;
    member this.GetDiscountAmount() = this.UnitPrice * this.DiscountRate / 100.00;
    member this.MarkedPrice() = this.UnitPrice - this.GetDiscountAmount();
    new() = StoreItem("", "", "", "", "", "", 0.00, 0.00) 
    new(number, make, category, subcategory, name, size, price) = StoreItem(number, make, category, subcategory, name, size, price, 0.00) 
 
let storeItems = [| new StoreItem(); new StoreItem(); new StoreItem(); new StoreItem(); new StoreItem(); |];
 
Array.set storeItems 1 (StoreItem("948596", "Tommy Hilfiger", "Men", "Shirts", "Texture Oxford Slim Fit Long Sleeve Dress Shirt", "17 34/35", 47.75))
Array.set storeItems 3 (StoreItem("497960", "Kenneth Cole Reaction", "Men", "Shirts", "Dress Shirt, Urban Satin", "16.5 36/37", 37.75))
 
printfn "Store Item: %A: " storeItems.[0]
printfn "________________ Store Items _______________________________"
printfn "============================================================"
for storeItem in storeItems do
    printfn "Item #:          %s" storeItem.ItemNumber;
    printfn "Manufacturer:    %s" storeItem.Manufacturer;
    printfn "Category:        %s" storeItem.Category;
    printfn "Sub-Category:    %s" storeItem.SubCategory;
    printfn "Item Name:       %s" storeItem.ItemName;
    printfn "Item Size:       %s" storeItem.ItemSize;
    printfn "Unit Price:      %0.02f" storeItem.UnitPrice;
    printfn "Discount Rate:   %0.0f%s" storeItem.DiscountRate "%";
    printfn "Discount Amount: %0.02f" (storeItem.GetDiscountAmount());
    printfn "Marked Price:    %0.02f" (storeItem.MarkedPrice());
    printfn "------------------------------------------------------------"

This would produce:

________________ Store Items _______________________________
============================================================
Item #:
Manufacturer:
Category:
Sub-Category:
Item Name:
Item Size:
Unit Price:      0.00
Discount Rate:   0%
Discount Amount: 0.00
Marked Price:    0.00
------------------------------------------------------------
Item #:          948596
Manufacturer:    Tommy Hilfiger
Category:        Men
Sub-Category:    Shirts
Item Name:       Texture Oxford Slim Fit Long Sleeve Dress Shirt
Item Size:       17 34/35
Unit Price:      47.75
Discount Rate:   0%
Discount Amount: 0.00
Marked Price:    47.75
------------------------------------------------------------
Item #:
Manufacturer:
Category:
Sub-Category:
Item Name:
Item Size:
Unit Price:      0.00
Discount Rate:   0%
Discount Amount: 0.00
Marked Price:    0.00
------------------------------------------------------------
Item #:          497960
Manufacturer:    Kenneth Cole Reaction
Category:        Men
Sub-Category:    Shirts
Item Name:       Dress Shirt, Urban Satin
Item Size:       16.5 36/37
Unit Price:      37.75
Discount Rate:   0%
Discount Amount: 0.00
Marked Price:    37.75
------------------------------------------------------------
Item #:
Manufacturer:
Category:
Sub-Category:
Item Name:
Item Size:
Unit Price:      0.00
Discount Rate:   0%
Discount Amount: 0.00
Marked Price:    0.00
------------------------------------------------------------
Press any key to close this window . . .

Initialyzing an Array Using an Expression

Another way to create an array is to provide its values using an expression. To support this, the Array module provides a function named init. Its signature is:

Array.init : int -> (int -> 'T) -> 'T []

Here is an example:

let yCoords = Array.init 8 (fun a -> (2 * a) + 1);

printfn "Y Coordinates: %A" yCoords;

This would produce:

Y Coordinates: [|1; 3; 5; 7; 9; 11; 13; 15|]
Press any key to close this window . . .

Copying a Fraction of an Array

You can get the fraction of an array and copy that fraction into another array. This operation can be carried by the blit() function of the Array module. Its signature is:

Array.blit : 'T [] -> int -> 'T [] -> int -> int -> unit

This method takes five arguments. The first argument is the array that holds the original value. It is called the source array. The third argument is the array that will receive the fraction. This is called the target array. The target can contain some or all values. This means that some values could have default or unnecessary values. The second argument is the starting index from which to copy values from the source array. The fourth argument is the starting index where to start adding the values that were copied from the source. The last (fifth) argument is the number of items to copy from the source, of course starting from the index specified by the second argument. Here is an example:

type StoreItem(number, make, category, subcategory, name, size, price, discrate) =
    let mutable nbr = number
    let mutable mk = make
    let mutable cat = category
    let mutable sub = subcategory
    let mutable nm = name
    let mutable sz = size
    let mutable prc = price
    let mutable rate = discrate
 
    member this.ItemNumber   with get() = nbr  and set(value) = nbr  <- value;
    member this.Manufacturer with get() = mk   and set(value) = mk   <- value;
    member this.Category     with get() = cat  and set(value) = cat  <- value;
    member this.SubCategory  with get() = sub  and set(value) = sub  <- value;
    member this.ItemName     with get() = nm   and set(value) = nm   <- value;
    member this.ItemSize     with get() = sz   and set(value) = sz   <- value;
    member this.UnitPrice    with get() = prc  and set(value) = prc  <- value;
    member this.DiscountRate with get() = rate and set(value) = rate <- value;
    member this.GetDiscountAmount() = this.UnitPrice * this.DiscountRate / 100.00;
    member this.MarkedPrice() = this.UnitPrice - this.GetDiscountAmount();
    new() = StoreItem("", "", "", "", "", "", 0.00, 0.00) 
    new(number, make, category, subcategory, name, size, price) = StoreItem(number, make, category, subcategory, name, size, price, 0.00) 
 
let storeItems = [| StoreItem("441180", "Ralph Lauren", "Girls", "Shirts", "Girls 2-6X Short-Sleeved Mesh Polo Shirt", "3/3T", 34.95);
                    StoreItem("292915", "Kenneth Cole", "Women", "Dresses", "Three-Quarter Sleeved Dress", "L", 145.50, 20.00);
                    StoreItem("479160", "Polo Ralph Lauren", "Men", "Pants", "Classic Straight-Leg Jeans", "33W - 32L", 84.85);
                    StoreItem("561150", "Kenneth Cole", "Women", "Dresses", "Three-Quarter Sleeved Dress", "XS", 145.50);
                    StoreItem("689771", "Calvin Klein", "Men", "Pants", "Straight Leg Jean in Black Wash", "38/30", 45.00, 25.00);
                    StoreItem("570810", "Nautica", "Boys", "Sweaters", "Boys 2-7 Cashmere Cable V-neck Sweater", "2T/3T", 145.00);
                 |];
 
// Here is a new array with empty values
let arrivals = [| StoreItem("428741", "Guess", "Girls", "Dresses", "Girls 2-6X Denim Print Ruffled Dress", "3T", 34.95, 35.00);
                 StoreItem(); StoreItem(); |]
// Copy the items from the third position (index = 2) of the storeItems (the source) array.
// Add them from the second position (index = 1) of the blitter array (the target).
// From the source array, copy 3 items 
Array.blit storeItems 3 arrivals 1 2;
 
printfn "________________ Store Items _______________________________"
printfn "============================================================"
for storeItem in arrivals do
    printfn "Item #:          %s" storeItem.ItemNumber;
    printfn "Manufacturer:    %s" storeItem.Manufacturer;
    printfn "Category:        %s" storeItem.Category;
    printfn "Sub-Category:    %s" storeItem.SubCategory;
    printfn "Item Name:       %s" storeItem.ItemName;
    printfn "Item Size:       %s" storeItem.ItemSize;
    printfn "Unit Price:      %0.02f" storeItem.UnitPrice;
    printfn "Discount Rate:   %0.0f%s" storeItem.DiscountRate "%";
    printfn "Discount Amount: %0.02f" (storeItem.GetDiscountAmount());
    printfn "Marked Price:    %0.02f" (storeItem.MarkedPrice());
    printfn "------------------------------------------------------------"

This would produce:

________________ Store Items _______________________________
============================================================
Item #:          428741
Manufacturer:    Guess
Category:        Girls
Sub-Category:    Dresses
Item Name:       Girls 2-6X Denim Print Ruffled Dress
Item Size:       3T
Unit Price:      34.95
Discount Rate:   35%
Discount Amount: 12.23
Marked Price:    22.72
------------------------------------------------------------
Item #:          561150
Manufacturer:    Kenneth Cole
Category:        Women
Sub-Category:    Dresses
Item Name:       Three-Quarter Sleeved Dress
Item Size:       XS
Unit Price:      145.50
Discount Rate:   0%
Discount Amount: 0.00
Marked Price:    145.50
------------------------------------------------------------
Item #:          689771
Manufacturer:    Calvin Klein
Category:        Men
Sub-Category:    Pants
Item Name:       Straight Leg Jean in Black Wash
Item Size:       38/30
Unit Price:      45.00
Discount Rate:   25%
Discount Amount: 11.25
Marked Price:    33.75
------------------------------------------------------------
Press any key to close this window . . .

Copying an Array

If you have a good array you want to use in a particular scenario without messing with the original array, you can make a copy. This can be done through the copy() function of the Array module. Its signature is:

Array.copy : 'T [] -> 'T []

This function takes one argument as the array that holds the values.

Appending an Array

Appending an array consists of adding one array to another array and getting the resulting group as a new array. This operation is available through the append() function of the Array module. Its signature is:

Array.append : 'T [] -> 'T [] -> 'T []

This function takes two arguments, each is an array. The values of the second array will be added to the right side of the values of the first array. The result is a new array. Here is an example of calling the method:

let week1 = [| 8.00; 8.50;  8.00; 9.00; 8.00; 0.00; 0.00; |]
let week2 = [| 8.50; 9.50; 10.00; 8.50; 9.50; 0.00; 0.00; |]
 
let payrollTimes = Array.append week1 week2
printfn "Times Worked: %A" payrollTimes

This would produce:

Times Worked: [|8.0; 8.5; 8.0; 9.0; 8.0; 0.0; 0.0; 8.5; 9.5; 10.0; 8.5; 9.5; 0.0; 0.0|]
Press any key to close this window . . .

Creating a Sub-Array

A sub-array is an array extracted from values of an existing array. To let you create a sub-array, the Array module provides the sub() function. Its signature is:

Array.sub : 'T [] -> int -> int -> 'T []

This function takes three arguments. The first is the array that holds the values. The second and the third arguments specify the range to consider in the array. The method returns a new array. Here is an example:

type OccupancyStatus =
| Other       = 0
| Available   = 1
| Occupied    = 2
| NeedsRepair = 3
| NotReady    = 4
 
type Apartment = {
    UnitNumber      : string
    Bedrooms        : int
    Bathrooms       : float
    SecurityDeposit : int
    MonthlyRate     : int
    Status          : OccupancyStatus }
 
let apartments = [|
    { UnitNumber = "101"; Bedrooms = 2; Bathrooms = 2.00; SecurityDeposit =  650; MonthlyRate = 1150; Status = OccupancyStatus.Available   }
    { UnitNumber = "102"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  500; MonthlyRate =  950; Status = OccupancyStatus.NeedsRepair }
    { UnitNumber = "103"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  500; MonthlyRate =  925; Status = OccupancyStatus.Available   }
    { UnitNumber = "104"; Bedrooms = 3; Bathrooms = 2.00; SecurityDeposit =  850; MonthlyRate = 1350; Status = OccupancyStatus.Occupied    }
    { UnitNumber = "105"; Bedrooms = 2; Bathrooms = 1.00; SecurityDeposit =  550; MonthlyRate = 1150; Status = OccupancyStatus.Available   }
    { UnitNumber = "106"; Bedrooms = 3; Bathrooms = 2.00; SecurityDeposit = 1350; MonthlyRate =  850; Status = OccupancyStatus.Available   }
    { UnitNumber = "107"; Bedrooms = 3; Bathrooms = 2.00; SecurityDeposit = 1285; MonthlyRate =  850; Status = OccupancyStatus.NotReady    }
    { UnitNumber = "108"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  885; MonthlyRate =  500; Status = OccupancyStatus.Available   }
    { UnitNumber = "109"; Bedrooms = 2; Bathrooms = 2.00; SecurityDeposit = 1150; MonthlyRate =  650; Status = OccupancyStatus.Available   }
    { UnitNumber = "110"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  895; MonthlyRate =  500; Status = OccupancyStatus.Available   }
 |]
 
let units = Array.sub apartments 2 5;
 
printfn "====================================================="
printfn "\t\t\tMonthly"
printfn "Unit # Beds\tBaths\tRent\tDeposit Status"
printfn "-----------------------------------------------------"
for n = 0 to (Array.length units) - 1 do
    printfn "%s\t%i\t%.2f\t%d\t%d\t%A" units.[n].UnitNumber units.[n].Bedrooms units.[n].Bathrooms units.[n].MonthlyRate units.[n].SecurityDeposit units.[n].Status
printfn "-----------------------------------------------------"

This would produce:

=====================================================
                        Monthly
Unit # Beds     Baths   Rent    Deposit Status
-----------------------------------------------------
103     1       1.00    925     500     Available
104     3       2.00    1350    850     Occupied
105     2       1.00    1150    550     Available
106     3       2.00    850     1350    Available
107     3       2.00    850     1285    NotReady
-----------------------------------------------------
Press any key to close this window . . .

Iterating Through an Array

Getting an Item Based on its Index

We already know that you can use a for loop to visit each member of an array. As an alternative, to let you access an item based on its index, the Array module provides a function named get. Its signature is:

Array.get : 'T [] -> int -> 'T

This function takes two arguments. The first is the array that holds the values. The second argument is the index of the item you want. Here is an example:

type Employee = {
    EmployeeNumber : string
    FirstName      : string
    LastName       : string
    HourlySalary   : double }
 
let employees = [| { EmployeeNumber = "8022-3840"; FirstName = "Mark";      LastName = "Plant";    HourlySalary = 24.55 };
                   { EmployeeNumber = "5840-2497"; FirstName = "Carol";     LastName = "Mylans";   HourlySalary = 16.25 };
                   { EmployeeNumber = "7042-8150"; FirstName = "Frank";     LastName = "Cranston"; HourlySalary = 35.44 };
                   { EmployeeNumber = "2081-7008"; FirstName = "Maria";     LastName = "Pappas";   HourlySalary = 15.26 };
                   { EmployeeNumber = "4295-8475"; FirstName = "Alexander"; LastName = "Fays";     HourlySalary = 22.75 }; |]
 
printfn "Employees Records ___________"
for n = 0 to employees.Length - 1 do
    let empl = Array.get employees n;
    printfn "=-=-=-=-=-=-=-=-=-=-=-=-="
    printfn "Employee Record"
    printfn "-------------------------"
    printfn "Employee #:    %s" empl.EmployeeNumber
    printfn "First Name:    %s" empl.FirstName
    printfn "Last Name:     %s" empl.LastName
    printfn "Hourly Salary: %.02F" empl.HourlySalary
printfn "=============================================="

This would produce:

Employees Records ___________
=-=-=-=-=-=-=-=-=-=-=-=-=
Employee Record
-------------------------
Employee #:    8022-3840
First Name:    Mark
Last Name:     Plant
Hourly Salary: 24.55
=-=-=-=-=-=-=-=-=-=-=-=-=
Employee Record
-------------------------
Employee #:    5840-2497
First Name:    Carol
Last Name:     Mylans
Hourly Salary: 16.25
=-=-=-=-=-=-=-=-=-=-=-=-=
Employee Record
-------------------------
Employee #:    7042-8150
First Name:    Frank
Last Name:     Cranston
Hourly Salary: 35.44
=-=-=-=-=-=-=-=-=-=-=-=-=
Employee Record
-------------------------
Employee #:    2081-7008
First Name:    Maria
Last Name:     Pappas
Hourly Salary: 15.26
=-=-=-=-=-=-=-=-=-=-=-=-=
Employee Record
-------------------------
Employee #:    4295-8475
First Name:    Alexander
Last Name:     Fays
Hourly Salary: 22.75
==============================================
Press any key to close this window . . .

Iterating an Array

To support the ability to execute a function on each member of an array, the Array module provides a function named iter. Its signature is:

Array.iter : ('T -> unit) -> 'T [] -> unit

This method takes two arguments. The first argument is a function that will be applied to each member of the array. The second argument is the array that holds the values. Here is an example:

type OccupancyStatus =
| Other       = 0
| Available   = 1
| Occupied    = 2
| NeedsRepair = 3
 
type Apartment = {
    UnitNumber      : string
    Bedrooms        : int
    Bathrooms       : float
    SecurityDeposit : int
    MonthlyRate     : int
    Status          : OccupancyStatus }
 
let apartments = Array.create 5 { UnitNumber = "101"; Bedrooms = 2; Bathrooms = 2.00; SecurityDeposit = 650; MonthlyRate = 1150; Status = OccupancyStatus.Available };
 
apartments.[1] <- { UnitNumber = "102"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit = 500; MonthlyRate =  950; Status = OccupancyStatus.NeedsRepair }
apartments.[2] <- { UnitNumber = "103"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit = 500; MonthlyRate =  925; Status = OccupancyStatus.Available   }
apartments.[3] <- { UnitNumber = "104"; Bedrooms = 3; Bathrooms = 2.00; SecurityDeposit = 850; MonthlyRate = 1350; Status = OccupancyStatus.Occupied    }
apartments.[4] <- { UnitNumber = "105"; Bedrooms = 2; Bathrooms = 1.00; SecurityDeposit = 550; MonthlyRate = 1150; Status = OccupancyStatus.Available   }
 
printfn "====================================================="
printfn "\t\t\tMonthly"
printfn "Unit # Beds\tBaths\tRent\tDeposit Status"
printfn "-----------------------------------------------------"
Array.iter (fun (apart : Apartment) -> printfn "%s\t%i\t%.2f\t%d\t%d\t%A" apart.UnitNumber apart.Bedrooms apart.Bathrooms apart.MonthlyRate apart.SecurityDeposit apart.Status) apartments;
printfn "-----------------------------------------------------"

This would produce:

=====================================================
                        Monthly
Unit # Beds     Baths   Rent    Deposit Status
-----------------------------------------------------
101     2       2.00    1150    650     Available
102     1       1.00    950     500     NeedsRepair
103     1       1.00    925     500     Available
104     3       2.00    1350    850     Occupied
105     2       1.00    1150    550     Available
-----------------------------------------------------
Press any key to close this window . . .

Conditional Arrays

The Existense of an Item in an Array

To let you find out whether an item exists in an array, the Array module provides a function named exists. Its signature is:

Array.exists : ('T -> bool) -> 'T list -> bool

This is a Boolean function that takes two arguments. The first is a statement that will scan the whole array to test the condition by which a member of the array exists. If a member responds to the conditional existence, the function returns true. If no member of the array responds to that condition, the function concludes that there is no member that responds and the function returns false. Here is an example:

type Employee = {
    EmployeeNumber : string
    FirstName      : string
    LastName       : string
    HourlySalary   : double }
 
let employees = [| { EmployeeNumber = "8022-3840"; FirstName = "Mark";  LastName = "Plant";  HourlySalary = 24.55 };
                   { EmployeeNumber = "5840-2497"; FirstName = "Carol"; LastName = "Mylans"; HourlySalary = 16.25 };
                   { EmployeeNumber = "2081-7008"; FirstName = "Maria"; LastName = "Pappas"; HourlySalary = 22.75 }; |]
 
type PayrollPreparation(number, times) =
    let mutable nbr = number;
    let mutable tms = times;
    member this.EmployeeeNumber with get() = nbr and set(value) = nbr <- value;
    member this.TimesWorked with get() = tms and set(value) = tms <- value;
    member this.PaySummary(hourlySalary) : float array =
        let mutable totalWeekTime = 0.00
        
        for t in tms do totalWeekTime <- totalWeekTime + t
 
        // If the employee worked under 40 hours, there is no overtime
        if totalWeekTime < 40. then
            [| totalWeekTime; 0.00; hourlySalary * totalWeekTime; 0.00; hourlySalary * totalWeekTime |]
        else // if totalWeekTime >= 40. then
            [| 40.00; totalWeekTime - 40.00; hourlySalary * 40.00; (totalWeekTime - 40.00) * (hourlySalary * 1.50); hourlySalary * 40.00 + ((totalWeekTime - 40.00) * (hourlySalary * 1.50)) |]
 
let pp = PayrollPreparation("5840-2497", [| 6.0; 7.5; 8.0; 6.5; 7.5; 0.0; 0.0 |]);
//let pp = PayrollPreparation("8022-3840", [| 8.50; 9.50; 10.00; 8.50; 9.50; 0.0; 0.0 |]);
 
if (Array.exists (fun (empl : Employee) -> empl.EmployeeNumber = pp.EmployeeeNumber) employees) then
    let mutable salary = 0.00
 
    do
        for empl in employees do
            if empl.EmployeeNumber = pp.EmployeeeNumber then salary <- empl.HourlySalary;
    printfn "======================================"
    printfn "Employee Payroll"
    printfn "--------------------------------------"
    printfn "Employee #:\t\t\t%s" pp.EmployeeeNumber;
    printf "Full Name:\t\t\t"
    do
        for empl in employees do
            if empl.EmployeeNumber = pp.EmployeeeNumber then printfn "%s, %s" empl.LastName empl.FirstName;
    printfn "Hourly Salary:\t\t%.02F" salary;
    printfn "Pay Summary___________________________"
    for i = 0 to (pp.PaySummary(salary)).Length - 1 do
        printfn "%s\t%0.02f" [| "Regular Time:   ";
                                "Overtime:       ";
                                "Regular Amount: ";
                                "Overtime Salary:";
                                "Net Pay:        " |].[i]
                               (pp.PaySummary(salary)).[i]
    printfn "--------------------------------------"
else
    printfn "There is no employee with that number.";

Mapping an Array

Mapping allows you to check something on an array. If the array is made of objects, one way you can map is to get the values of only one member of the class or structure. One way you can perform this operation is to call the map() method of the Array module. Its signature is:

Array.map : ('T -> 'U) -> 'T [] -> 'U []

This function takes two arguments. The first is a function. If the array is made of objects, the function can consist of simply selecting a property or calling a method from the class. The second argument is the array that holds the values. Here is an example of calling it:

type RoadType =
    | Court
    | Street
    | Road
    | Avenue
    | Boulevard
    | StateHighway
    | Interstate
    | Unknown
    
type RoadSystem = {
    RoadName : string
    Category : RoadType
    Distance : float
    Location : string
    Intersections : string array }
 
let roads = [| { RoadName = "MD 410"; Category = RoadType.Road; Distance = 13.92; Location = "From East Bethesda to Pennsy Drive in Landover Hills"; Intersections = [| "MD 355"; "MD 187"; "Maple Ave"; "MD 185"; "Colesville Rd" |] };
               { RoadName = "I 5"; Category = RoadType.Interstate; Distance = 796.432; Location = "From  Mexico–United States border to South of Oregon"; Intersections = [| "SR 15"; "I 8"; "I-10"; "I-210"; "SR 99"; "I-580"; "I-80"; |] };
               { RoadName = "NE 14"; Category = RoadType.StateHighway; Distance = 203.54; Location = "From Superior, KS to SD 37"; Intersections = [| "NE 8"; "US 136"; "NE 74"; ""; "NE 41"; "US 6"; "I 80"; "US 34"; "NE 66"; "US 30"; "NE 92"; "NE 22" |] };
               { RoadName = "I 296"; Category = RoadType.Interstate; Distance = 3.43; Location = "Michigan"; Intersections = [||] };
               { RoadName = "US 2"; Category = RoadType.Road; Distance = 2571.00; Location = "Western Segment From Washington Rte 529 to I 75 in Michigan; Eastern Segment From US 11 in NY to I-95 in Maine."; Intersections = [| "US 395"; "I 15"; "US 87"; "US 83"; "I 29" |] }; |]
 
// Selecing on the RoadName property of the class
let roadsNames = Array.map (function (road : RoadSystem) -> road.RoadName) roads;
 
printf "Road Names: "
for road in roadsNames do
    printf "(%s) " road
printfn "\n=------------------------------------------------="

This would produce:

Road Names: (MD 410) (I 5) (NE 14) (I 296) (US 2)
=------------------------------------------------=
Press any key to close this window . . .

Another way to map an array of objects is to find out whether the values of members respond to a certain condition. In the following example, we apply a condition when calling the Array.map() method to find out whether a road is an Interstate:

type RoadType =
    | Court
    | Street
    | Road
    | Avenue
    | Boulevard
    | StateHighway
    | Interstate
    | Unknown
    
type RoadSystem = {
    RoadName : string
    Category : RoadType
    Distance : float
    Location : string
    Intersections : string array }
 
let roads = [| { RoadName = "MD 410"; Category = RoadType.Road; Distance = 13.92; Location = "From East Bethesda to Pennsy Drive in Landover Hills"; Intersections = [| "MD 355"; "MD 187"; "Maple Ave"; "MD 185"; "Colesville Rd" |] };
               { RoadName = "I 5"; Category = RoadType.Interstate; Distance = 796.432; Location = "From  Mexico–United States border to South of Oregon"; Intersections = [| "SR 15"; "I 8"; "I-10"; "I-210"; "SR 99"; "I-580"; "I-80"; |] };
               { RoadName = "NE 14"; Category = RoadType.StateHighway; Distance = 203.54; Location = "From Superior, KS to SD 37"; Intersections = [| "NE 8"; "US 136"; "NE 74"; ""; "NE 41"; "US 6"; "I 80"; "US 34"; "NE 66"; "US 30"; "NE 92"; "NE 22" |] };
               { RoadName = "I 296"; Category = RoadType.Interstate; Distance = 3.43; Location = "Michigan"; Intersections = [||] };
               { RoadName = "US 2"; Category = RoadType.Road; Distance = 2571.00; Location = "Western Segment From Washington Rte 529 to I 75 in Michigan; Eastern Segment From US 11 in NY to I-95 in Maine."; Intersections = [| "US 395"; "I 15"; "US 87"; "US 83"; "I 29" |] }; |]
 
let roadsNames = Array.map (function (road : RoadSystem) -> road.Category = RoadType.Interstate) roads;
 
printfn "Interstates: %A" roadsNames;

This would produce:

Road Names: [|false; true; false; true; false|]
Press any key to close this window . . .

Finding Items in an Array

To let you find an item in an array, the Array module has a function 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:

type Employee = {
    EmployeeNumber : string
    FirstName      : string
    LastName       : string
    HourlySalary   : double }
 
let employees = [| { EmployeeNumber = "8022-3840"; FirstName = "Marianne";  LastName = "Jeyffers";  HourlySalary = 24.55 };
                   { EmployeeNumber = "5840-2497"; FirstName = "Caroline";  LastName = "Gonzalez";  HourlySalary = 16.25 };
                   { EmployeeNumber = "7042-8150"; FirstName = "Thomas";    LastName = "Cranston";  HourlySalary = 35.44 };
                   { EmployeeNumber = "2081-7008"; FirstName = "Jeannette"; LastName = "Pappasie";  HourlySalary = 15.26 };
                   { EmployeeNumber = "4295-8475"; FirstName = "Alexander"; LastName = "Donaldson"; HourlySalary = 22.75 }; |]
 
type PayrollPreparation(number, times) =
    let mutable nbr = number;
    let mutable tms = times;
    member this.EmployeeeNumber with get() = nbr and set(value) = nbr <- value;
    member this.TimesWorked with get() = tms and set(value) = tms <- value;
    member this.CalculateTotalTime() =
        let mutable sum = 0.00
        for t in tms do sum <- sum + t
        sum
    member this.CalculateWeeklySalary() =
        let mutable salary = 0.00;
        let empl = Array.find (fun (empl : Employee) -> empl.EmployeeNumber = nbr) employees
        this.CalculateTotalTime() * empl.HourlySalary
 
printfn "Employees Records _______________________________"
printfn "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
printfn "\t\t\t\t\tHourly"
printfn "Empl #     First Name   Last Name\tSalary"
printfn "-------------------------------------------------"
for n = 0 to employees.Length - 1 do
    let empl = Array.get employees n;
    printfn "%s  %s\t%s\t%.02F" empl.EmployeeNumber empl.FirstName empl.LastName empl.HourlySalary
printfn "================================================="

This would produce:

Employees Records _______________________________
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
                                        Hourly
Empl #     First Name   Last Name       Salary
-------------------------------------------------
8022-3840  Marianne     Jeyffers        24.55
5840-2497  Caroline     Gonzalez        16.25
7042-8150  Thomas       Cranston        35.44
2081-7008  Jeannette    Pappasie        15.26
4295-8475  Alexander    Donaldson       22.75
=================================================
Press any key to close this window . . .

Picking an Element from an Array

The Array module provides a function that can be used to apply a condition to the elements from the first item to the last. The function returns the first item that responds true to the condition. The function is named pick and its signature is:

Array.pick : ('T -> 'U option) -> 'T [] -> 'U

The condition is created as a function in the first argument of the function. That condition is created as a matching option. The second argument is the array that holds the values. Here is an example of calling the function:

type Employee = {
    EmployeeNumber : string
    FirstName      : string
    LastName       : string
    HourlySalary   : double }
 
let employees = [| { EmployeeNumber = "8022-3840"; FirstName = "Mark";  LastName = "Plant";  HourlySalary = 24.55 };
                   { EmployeeNumber = "5840-2497"; FirstName = "Carol"; LastName = "Mylans"; HourlySalary = 16.25 };
                   { EmployeeNumber = "2081-7008"; FirstName = "Maria"; LastName = "Pappas"; HourlySalary = 22.75 }; |]
 
type PayrollPreparation(number, times) =
    let mutable nbr = number;
    let mutable tms = times;
    member this.EmployeeeNumber with get() = nbr and set(value) = nbr <- value;
    member this.TimesWorked with get() = tms and set(value) = tms <- value;
    member this.PaySummary() : float array =
        let mutable regularTime = 0.00
        let mutable overtime = 0.00
        let mutable regularAmount = 0.00
        let mutable overtimeSalary = 0.00
        let mutable totalWeekTime = 0.00
        let mutable overtimeAmount = 0.00
        
        let empl = Array.pick (fun (staff : Employee) ->
            match staff.EmployeeNumber with
            | nbr -> Some staff
            | _ -> None) employees
 
        for t in tms do totalWeekTime <- totalWeekTime + t
        overtimeSalary <- empl.HourlySalary * 1.50
 
        // If the employee worked under 40 hours, there is no overtime
        if totalWeekTime < 40. then
            regularTime <- totalWeekTime
            regularAmount <- empl.HourlySalary * regularTime
            //overtime <- 0.00
            //overtimeAmount <- 0.00
            [| regularTime; 0.00; regularAmount; 0.00; regularAmount |]
        // If the employee worked over 40 hours, calculate the overtime
        else //if totalWeekTime >= 40. then
            regularTime <- 40.
            regularAmount <- empl.HourlySalary * 40.
            overtime <- totalWeekTime - 40.
            overtimeAmount <- overtime * overtimeSalary
            [| 40.; overtime; regularAmount; overtimeAmount; regularAmount + overtimeAmount |]
 
//let pp = PayrollPreparation("5840-2497", [| 6.0; 7.5; 8.0; 6.5; 7.5; 0.0; 0.0 |]);
let pp = PayrollPreparation("8022-3840", [| 8.50; 9.50; 10.00; 8.50; 9.50; 0.0; 0.0 |]);
 
let empl = Array.pick (fun (staff : Employee) ->
    match staff.EmployeeNumber with
    | "8022-3840" -> Some staff
    | _ -> None) employees
 
printfn "======================================"
printfn "Employee Payroll"
printfn "--------------------------------------"
printfn "Employee #:\t\t%s" pp.EmployeeeNumber;
printf "Full Name:\t\t"
do
    for empl in employees do
        if empl.EmployeeNumber = pp.EmployeeeNumber then printfn "%s, %s" empl.LastName empl.FirstName;
printfn "Hourly Salary:\t\t%.02F" empl.HourlySalary;
printfn "Pay Summary___________________________"
for i = 0 to 4 do
    printfn "%s\t%0.02f" [| "Regular Time:   ";
                            "Overtime:       ";
                            "Regular Amount: ";
                            "Overtime Salary:";
                            "Net Pay:        " |].[i]
                           (pp.PaySummary()).[i]
    printfn "--------------------------------------"

This would produce:

======================================
Employee Payroll
--------------------------------------
Employee #:             8022-3840
Full Name:              Plant, Mark
Hourly Salary:          24.55
Pay Summary___________________________
Regular Time:           40.00
--------------------------------------
Overtime:               6.00
--------------------------------------
Regular Amount:         982.00
--------------------------------------
Overtime Salary:        220.95
--------------------------------------
Net Pay:                1202.95
--------------------------------------
Press any key to close this window . . .

Filtering Items

Filtering items consists of applying a condition to the values of the array. The values that respond to the condition are selected and stored in a new array that is the result of the operation. To support this operation, the Array module provides the filter() function. Its signature is:

Array.filter : ('T -> bool) -> 'T [] -> 'T []

This method takes two arguments and returns an array. The first argument is a condition to apply to each value of the array that is the second argument. Here is an example:

Here is an example:

type StoreItem(number, make, category, subcategory, name, size, price, discrate) =
    let mutable nbr = number
    let mutable mk = make
    let mutable cat = category
    let mutable sub = subcategory
    let mutable nm = name
    let mutable sz = size
    let mutable prc = price
    let mutable rate = discrate
 
    member this.ItemNumber   with get() = nbr  and set(value) = nbr  <- value;
    member this.Manufacturer with get() = mk   and set(value) = mk   <- value;
    member this.Category     with get() = cat  and set(value) = cat  <- value;
    member this.SubCategory  with get() = sub  and set(value) = sub  <- value;
    member this.ItemName     with get() = nm   and set(value) = nm   <- value;
    member this.ItemSize     with get() = sz   and set(value) = sz   <- value;
    member this.UnitPrice    with get() = prc  and set(value) = prc  <- value;
    member this.DiscountRate with get() = rate and set(value) = rate <- value;
    member this.GetDiscountAmount() = this.UnitPrice * this.DiscountRate / 100.00;
    member this.MarkedPrice() = this.UnitPrice - this.GetDiscountAmount();
    new(number, make, category, subcategory, name, size, price) = StoreItem(number, make, category, subcategory, name, size, price, 0.00) 
 
let storeItems = [| StoreItem("441180", "Ralph Lauren", "Girls", "Shirts", "Girls 2-6X Short-Sleeved Mesh Polo Shirt", "3/3T", 34.95);
                    StoreItem("292915", "Kenneth Cole", "Women", "Dresses", "Three-Quarter Sleeved Dress", "L", 145.50, 20.00);
                    StoreItem("479160", "Polo Ralph Lauren", "Men", "Pants", "Classic Straight-Leg Jeans", "33W - 32L", 84.85);
                    StoreItem("561150", "Kenneth Cole", "Women", "Dresses", "Three-Quarter Sleeved Dress", "XS", 145.50, 20.00);
                    StoreItem("689771", "Calvin Klein", "Men", "Pants", "Straight Leg Jean in Black Wash", "38/30", 45.00);
                    StoreItem("570810", "Nautica", "Boys", "Sweaters", "Boys 2-7 Cashmere Cable V-neck Sweater", "2T/3T", 145.00);
                 |];
 
let womenClothes = Array.filter (fun (si : StoreItem) -> si.Category = "Women") storeItems;
 
printfn "________________ Store Items _______________________________"
printfn "============================================================"
for storeItem in womenClothes do
    printfn "Item #:          %s" storeItem.ItemNumber;
    printfn "Manufacturer:    %s" storeItem.Manufacturer;
    printfn "Category:        %s" storeItem.Category;
    printfn "Sub-Category:    %s" storeItem.SubCategory;
    printfn "Item Name:       %s" storeItem.ItemName;
    printfn "Item Size:       %s" storeItem.ItemSize;
    printfn "Unit Price:      %0.02f" storeItem.UnitPrice;
    printfn "Discount Rate:   %0.0f%s" storeItem.DiscountRate "%";
    printfn "Discount Amount: %0.02f" (storeItem.GetDiscountAmount());
    printfn "Marked Price:    %0.02f" (storeItem.MarkedPrice());
    printfn "------------------------------------------------------------"

This would produce:

________________ Store Items _______________________________
============================================================
Item #:          292915
Manufacturer:    Kenneth Cole
Category:        Women
Sub-Category:    Dresses
Item Name:       Three-Quarter Sleeved Dress
Item Size:       L
Unit Price:      145.50
Discount Rate:   20%
Discount Amount: 29.10
Marked Price:    116.40
------------------------------------------------------------
Item #:          561150
Manufacturer:    Kenneth Cole
Category:        Women
Sub-Category:    Dresses
Item Name:       Three-Quarter Sleeved Dress
Item Size:       XS
Unit Price:      145.50
Discount Rate:   20%
Discount Amount: 29.10
Marked Price:    116.40
------------------------------------------------------------
Press any key to close this window . . .

Applying a Condition to All Items

To let you apply the same condition to all elements of an array, the Array module provides the forall() function. Its signature is:

Array.forall : ('T -> bool) -> 'T [] -> bool

The first of the two arguments is a Boolean function that applies a condition to each member of the array of the second argument. If all members of the array respond to the condition, the function returns true. If at least one member of the array doesn't apply to the condition, the function returns false. Here is an example:

type StoreItem(number, make, category, subcategory, name, size, price, discrate) =
    let mutable nbr = number
    let mutable mk = make
    let mutable cat = category
    let mutable sub = subcategory
    let mutable nm = name
    let mutable sz = size
    let mutable prc = price
    let mutable rate = discrate
 
    member this.ItemNumber   with get() = nbr  and set(value) = nbr  <- value;
    member this.Manufacturer with get() = mk   and set(value) = mk   <- value;
    member this.Category     with get() = cat  and set(value) = cat  <- value;
    member this.SubCategory  with get() = sub  and set(value) = sub  <- value;
    member this.ItemName     with get() = nm   and set(value) = nm   <- value;
    member this.ItemSize     with get() = sz   and set(value) = sz   <- value;
    member this.UnitPrice    with get() = prc  and set(value) = prc  <- value;
    member this.DiscountRate with get() = rate and set(value) = rate <- value;
    member this.GetDiscountAmount() = this.UnitPrice * this.DiscountRate / 100.00;
    member this.MarkedPrice() = this.UnitPrice - this.GetDiscountAmount();
    new(number, make, category, subcategory, name, size, price) = StoreItem(number, make, category, subcategory, name, size, price, 0.00) 
 
let storeItems = [| StoreItem("441180", "Ralph Lauren", "Girls", "Shirts", "Girls 2-6X Short-Sleeved Mesh Polo Shirt", "3/3T", 34.95);
                    StoreItem("292915", "Kenneth Cole", "Women", "Dresses", "Three-Quarter Sleeved Dress", "L", 145.50, 20.00);
                    StoreItem("479160", "Polo Ralph Lauren", "Men", "Pants", "Classic Straight-Leg Jeans", "33W - 32L", 84.85);
                    StoreItem("561150", "Kenneth Cole", "Women", "Dresses", "Three-Quarter Sleeved Dress", "XS", 145.50, 20.00);
                    StoreItem("689771", "Calvin Klein", "Men", "Pants", "Straight Leg Jean in Black Wash", "38/30", 45.00);
                    StoreItem("570810", "Nautica", "Boys", "Sweaters", "Boys 2-7 Cashmere Cable V-neck Sweater", "2T/3T", 145.00);
                 |];
 
let areAllItemsDiscounted = Array.forall (fun (si : StoreItem) -> si.DiscountRate > 0.00) storeItems;
 
printfn "Are all items discounted: %b" areAllItemsDiscounted

This would produce:

Are all items discounted: false
Press any key to close this window . . .

Choosing a Sub-Array

If you have an array with values that can be distinguished in categories, you can create a sub-array of items that respond to a particular criterion. To support this operation, the Array module provides a function named choose. Its signature is:

Array.choose : ('T -> 'U option) -> 'T [] -> 'U []

This function takes two arguments. The first argument is a matching statement that specifies a condition by which some values will be selected. The second argument is an array that holds the values. Here is an example of calling the function:

type OccupancyStatus =
| Other       = 0
| Available   = 1
| Occupied    = 2
| NeedsRepair = 3
| NotReady    = 4
 
type Apartment = {
    UnitNumber      : string
    Bedrooms        : int
    Bathrooms       : float
    SecurityDeposit : int
    MonthlyRate     : int
    Status          : OccupancyStatus }
 
let apartments = [|
    { UnitNumber = "101"; Bedrooms = 2; Bathrooms = 2.00; SecurityDeposit =  650; MonthlyRate = 1150; Status = OccupancyStatus.Available   }
    { UnitNumber = "102"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  500; MonthlyRate =  950; Status = OccupancyStatus.NeedsRepair }
    { UnitNumber = "103"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  500; MonthlyRate =  925; Status = OccupancyStatus.Available   }
    { UnitNumber = "104"; Bedrooms = 3; Bathrooms = 2.00; SecurityDeposit =  850; MonthlyRate = 1350; Status = OccupancyStatus.Occupied    }
    { UnitNumber = "105"; Bedrooms = 2; Bathrooms = 1.00; SecurityDeposit =  550; MonthlyRate = 1150; Status = OccupancyStatus.Available   }
    { UnitNumber = "106"; Bedrooms = 3; Bathrooms = 2.00; SecurityDeposit = 1350; MonthlyRate =  850; Status = OccupancyStatus.Available   }
    { UnitNumber = "107"; Bedrooms = 3; Bathrooms = 2.00; SecurityDeposit = 1285; MonthlyRate =  850; Status = OccupancyStatus.NotReady    }
    { UnitNumber = "108"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  885; MonthlyRate =  500; Status = OccupancyStatus.Available   }
    { UnitNumber = "109"; Bedrooms = 2; Bathrooms = 2.00; SecurityDeposit = 1150; MonthlyRate =  650; Status = OccupancyStatus.Available   }
    { UnitNumber = "110"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  895; MonthlyRate =  500; Status = OccupancyStatus.Available   }
 
 |]
 
printfn "All Apartments ======================================="
printfn "                       Monthly"
printfn "Unit # Beds\tBaths\tRent\tDeposit Status"
printfn "-----------------------------------------------------"
for n = 0 to (Array.length apartments) - 1 do
    printfn "%s\t%i\t%.2f\t%d\t%d\t%A" apartments.[n].UnitNumber apartments.[n].Bedrooms apartments.[n].Bathrooms apartments.[n].MonthlyRate apartments.[n].SecurityDeposit apartments.[n].Status
printfn "-----------------------------------------------------"
 
let choose = Array.choose (fun (apart : Apartment) -> 
    match apart.Bedrooms with
    | 1 -> Some(apart)
    | _ -> None) apartments;
 
printfn "One-Bedroom Apartments =============================="
printfn "                       Monthly"
printfn "Unit # Beds\tBaths\tRent\tDeposit Status"
printfn "-----------------------------------------------------"
for n = 0 to (Array.length choose) - 1 do
    printfn "%s\t%i\t%.2f\t%d\t%d\t%A" choose.[n].UnitNumber choose.[n].Bedrooms choose.[n].Bathrooms choose.[n].MonthlyRate choose.[n].SecurityDeposit choose.[n].Status
printfn "-----------------------------------------------------"

This would produce

All Apartments =======================================
                       Monthly
Unit # Beds     Baths   Rent    Deposit Status
-----------------------------------------------------
101     2       2.00    1150    650     Available
102     1       1.00    950     500     NeedsRepair
103     1       1.00    925     500     Available
104     3       2.00    1350    850     Occupied
105     2       1.00    1150    550     Available
106     3       2.00    850     1350    Available
107     3       2.00    850     1285    NotReady
108     1       1.00    500     885     Available
109     2       2.00    650     1150    Available
110     1       1.00    500     895     Available
-----------------------------------------------------
One-Bedroom Apartments ==============================
                       Monthly
Unit # Beds     Baths   Rent    Deposit Status
-----------------------------------------------------
102     1       1.00    950     500     NeedsRepair
103     1       1.00    925     500     Available
108     1       1.00    500     885     Available
110     1       1.00    500     895     Available
-----------------------------------------------------
Press any key to close this window . . .

Further Operations on Arrays

Getting a Reversed Array

Reversing an array consists of changing the order of its value. The reverse can be done using the rev() function of the Array module. Its signature is:

Array.rev : 'T [] -> 'T []

Here is an example:

type OccupancyStatus =
| Other       = 0
| Available   = 1
| Occupied    = 2
| NeedsRepair = 3
| NotReady    = 4
 
type Apartment = {
    UnitNumber      : string
    Bedrooms        : int
    Bathrooms       : float
    SecurityDeposit : int
    MonthlyRate     : int
    Status          : OccupancyStatus }
 
let apartments = [|
    { UnitNumber = "101"; Bedrooms = 2; Bathrooms = 2.00; SecurityDeposit =  650; MonthlyRate = 1150; Status = OccupancyStatus.Available   }
    { UnitNumber = "102"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  500; MonthlyRate =  950; Status = OccupancyStatus.NeedsRepair }
    { UnitNumber = "103"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  500; MonthlyRate =  925; Status = OccupancyStatus.Available   }
    { UnitNumber = "104"; Bedrooms = 3; Bathrooms = 2.00; SecurityDeposit =  850; MonthlyRate = 1350; Status = OccupancyStatus.Occupied    }
    { UnitNumber = "105"; Bedrooms = 2; Bathrooms = 1.00; SecurityDeposit =  550; MonthlyRate = 1150; Status = OccupancyStatus.Available   }
    { UnitNumber = "106"; Bedrooms = 3; Bathrooms = 2.00; SecurityDeposit = 1350; MonthlyRate =  850; Status = OccupancyStatus.Available   }
    { UnitNumber = "107"; Bedrooms = 3; Bathrooms = 2.00; SecurityDeposit = 1285; MonthlyRate =  850; Status = OccupancyStatus.NotReady    }
    { UnitNumber = "108"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  885; MonthlyRate =  500; Status = OccupancyStatus.Available   }
    { UnitNumber = "109"; Bedrooms = 2; Bathrooms = 2.00; SecurityDeposit = 1150; MonthlyRate =  650; Status = OccupancyStatus.Available   }
    { UnitNumber = "110"; Bedrooms = 1; Bathrooms = 1.00; SecurityDeposit =  895; MonthlyRate =  500; Status = OccupancyStatus.Available   }
 
 |]
 
let reversedOrder = Array.rev apartments;
 
printfn "All Apartments ======================================="
printfn "                       Monthly"
printfn "Unit # Beds\tBaths\tRent\tDeposit Status"
printfn "-----------------------------------------------------"
for apart in reversedOrder do
    printfn "%s\t%i\t%.2f\t%d\t%d\t%A" apart.UnitNumber apart.Bedrooms apart.Bathrooms apart.MonthlyRate apart.SecurityDeposit apart.Status
printfn "-----------------------------------------------------"

This would produce:

All Apartments =======================================
                       Monthly
Unit # Beds     Baths   Rent    Deposit Status
-----------------------------------------------------
110     1       1.00    500     895     Available
109     2       2.00    650     1150    Available
108     1       1.00    500     885     Available
107     3       2.00    850     1285    NotReady
106     3       2.00    850     1350    Available
105     2       1.00    1150    550     Available
104     3       2.00    1350    850     Occupied
103     1       1.00    925     500     Available
102     1       1.00    950     500     NeedsRepair
101     2       2.00    1150    650     Available
-----------------------------------------------------
Press any key to close this window . . .

Number-Based Functions of Arrays

Introduction

The Array module of the Microsoft.FSharp.Collections namespace provides various functions to perform numeric calculations on the items of an array. To perform these calculations, all the members of the array must be numbers, whether integers or floats.

The Sum of Members of an Array

The sum() function is used to calculate the total of all the items of an array. The signature of that function is:

Array.sum : ^T [] -> ^T

This function takes one argument as the array that holds the values. Here is an example of calling the Array.sum() function:

type Employee = {
    EmployeeNumber : string
    FirstName      : string
    LastName       : string
    HourlySalary   : double }
 
let employees = [| { EmployeeNumber = "8022-3840"; FirstName = "Mark";  LastName = "Plant";  HourlySalary = 24.55 };
                   { EmployeeNumber = "5840-2497"; FirstName = "Carol"; LastName = "Mylans"; HourlySalary = 16.25 };
                   { EmployeeNumber = "2081-7008"; FirstName = "Maria"; LastName = "Pappas"; HourlySalary = 22.75 };
                   { EmployeeNumber = "2080-4813"; FirstName = "James"; LastName = "Alexanders"; HourlySalary = 22.25 }; |]
 
type PayrollPreparation(number, times) =
    let mutable nbr = number;
    let mutable tms = times;
    member this.EmployeeeNumber with get() = nbr and set(value) = nbr <- value;
    member this.TimesWorked with get() = tms and set(value) = tms <- value;
    member this.PaySummary() : float array =
        let mutable regularTime = 0.00
        let mutable overtime = 0.00
        let mutable regularAmount = 0.00
        let mutable overtimeSalary = 0.00
        let mutable overtimeAmount = 0.00
        
        let totalTime = Array.sum times
        
        let empl = Array.find (fun (empl : Employee) -> empl.EmployeeNumber = nbr) employees
 
        overtimeSalary <- empl.HourlySalary * 1.50
 
        // If the employee worked under 40 hours, there is no overtime
        if totalTime < 40. then
            regularTime <- totalTime
            regularAmount <- empl.HourlySalary * regularTime
            //overtime <- 0.00
            //overtimeAmount <- 0.00
            [| regularTime; 0.00; regularAmount; 0.00; regularAmount |]
        // If the employee worked over 40 hours, calculate the overtime
        else //if totalWeekTime >= 40. then
            regularTime <- 40.
            regularAmount <- empl.HourlySalary * 40.
            overtime <- totalTime - 40.
            overtimeAmount <- overtime * overtimeSalary
            [| 40.; overtime; regularAmount; overtimeAmount; regularAmount + overtimeAmount |]
 
// let pp = PayrollPreparation("5840-2497", [| 6.0; 7.5; 8.0; 6.5; 7.5; 0.0; 0.0 |]);
// let pp = PayrollPreparation("8022-3840", [| 8.50; 9.50; 10.00;  8.50; 9.50; 0.0; 0.0 |]);
let pp = PayrollPreparation("2080-4813", [| 8.50; 9.50; 10.50; 10.00; 9.00; 0.0; 0.0 |]);
 
let empl = Array.find (fun (empl : Employee) -> empl.EmployeeNumber = "2080-4813") employees
 
printfn "======================================"
printfn "Employee Payroll"
printfn "--------------------------------------"
printfn "Employee #:\t\t%s" pp.EmployeeeNumber;
printf "Full Name:\t\t"
do
    for empl in employees do
        if empl.EmployeeNumber = pp.EmployeeeNumber then printfn "%s, %s" empl.LastName empl.FirstName;
printfn "Hourly Salary:\t\t%.02F" empl.HourlySalary;
printfn "Pay Summary___________________________"
for i = 0 to 4 do
    printfn "%s\t%0.02f" [| "Regular Time:   ";
                            "Overtime:       ";
                            "Regular Amount: ";
                            "Overtime Salary:";
                            "Net Pay:        " |].[i]
                           (pp.PaySummary()).[i]
    printfn "--------------------------------------"

This would produce:

======================================
Employee Payroll
--------------------------------------
Employee #:             2080-4813
Full Name:              Alexanders, James
Hourly Salary:          22.25
Pay Summary___________________________
Regular Time:           40.00
--------------------------------------
Overtime:               7.50
--------------------------------------
Regular Amount:         982.00
--------------------------------------
Overtime Salary:        276.19
--------------------------------------
Net Pay:                1258.19
--------------------------------------
Press any key to close this window . . .

To let you apply a condition by which the sum should be calculated, the Array module provides a function named sumBy. Its signature is:

Array.sumBy : ('T -> ^U) -> 'T [] -> ^U

This function takes two arguments. The first is the function to apply to the array that is the second argument.


Previous Copyright © 2014-2024, FunctionX Thursday 02 November 2024 Next