Arrays in F# are mutable data types. I started intentionally with this line, as FSharp(F#) is functional programming language and the paradigm of language promotes immutability. So, whenever there is a mutable type or value be careful with the usage. Let’s go back to main topic i.e. Arrays. In this post, we’ll see how to initialize, iterate, update and other manipulation that you can do with Arrays in FSharp(F#). In this post, we’ll cover only one dimensional array. May be we can discuss 2D, 3D, and Jagged array in advanced array post of arrays in future.
Static array initialization
In FSharp(F#), we initialize the array with the following notations:
- let fruits = [|"Apple"; "Orange"; "Grapes"|]
-
- let fruits = [|
- "Apple"
- "Orange"
- "Grapes"
- |]
Notice additional symbol | (pipe) used with square braces to declare the array. Also the separator is no a "," comma anymore but it’s ; semicolon. Here’s an example of Array of integer sample and possible mistakes that can be done by a C# developer without getting any compile time error.
- let arr = [| 1; 2; 3; 4 |]
Possible mistakes #1
Possible mistakes #2
Initialization using sequence expressions
-
- let arr3 = [| for i in 1 .. 10 -> i * i |]
Output:
[|1; 4; 9; 16; 25; 36; 49; 64; 81; 100|]
Initialization using Array module
Array.empty
Creates a new array that does not contain any elements.
-
- let array1 = Array.empty<int>
-
- let array2 : int array = Array.empty
-
-
-
- let array3 = Array.empty
- printfn "Length of empty array: %d" array3.Length
Output: 0
Array.create
Creates an array of a specified size and sets all the elements to provided values.
-
- let arrayOfTenZeroes : int array = Array.create 10 -1
-
- let primeFlaggedArr : bool array = Array.create 10 true
Note: In the end of this article we’ll solve the find prime number problem using Sieve of Eratosthenes.
Array.zeroCreate
Creates an array, given a dimension and a function to generate the elements.
-
- let primeFlaggedArr : bool array = Array.zeroCreate 10
Array.init
Creates an array, given a dimension and a function to generate the elements.
-
- printfn "Array of squares: %A" (Array.init 10 (fun index -> index * index))
Accessing array elements
You can access array elements by using a dot operator (.) and brackets ([ and ]).
- let fruits = [|
- "Apple"
- "Orange"
- "Grapes"
- |]
- let firstFruit = fruits[0];
Accessing range of values from array using sliced notation,
-
- arr.[0..2]
-
- arr.[..2]
-
- arr.[2..]
Few more honorable mentions or generally used functions are Array.get, Array.set and Array.length which are self-explanatory.
Replacing existing value using index
Arrays are mutable so you can replace any existing value by accessing it via index and assigning a new value with ‘<-‘ operator.
-
- let fruits1 = [|
- "Apple"
- "Orange"
- "Grapes"
- |]
-
- fruits1.[0] <- "Mango"
-
- let print =
- for (fruit) in fruits1 do
- printfn "%s" fruit
Output:
>PrintUpper [|"Apple"; "Orange"; "Grapes"|] ;;
APPLE
ORANGE
GRAPES
Iterating through array elements
Let’s create a function that takes an array of string and converts the values to upper case.
- let MakeUpper(arr : string array) =
- for i in 0 .. arr.Length - 1 do
- Array.set arr i (arr.[i].ToUpper())
- printfn "%s" arr.[i]
In visual studio select the function and run it in F# interactive.
Output:
>MakeUpper [|"Apple"; "Orange"; "Grapes"|] ;;
APPLE
ORANGE
GRAPES
With variant of for loop (foreach alike)
- let PrintUpper(arr : string array) =
- for (fruit) in arr do
- printfn "%s" (fruit.ToUpper())
Output:
>PrintUpper [|"Apple"; "Orange"; "Grapes"|] ;;
APPLE
ORANGE
GRAPES
So now we are pretty much good to start with playing around array. Let’s try to solve few problems using array to get up to speed. As I discussed before we’ll be solving the finding prime number problem using
Sieve of Eratosthenes. Here’s a function to which is based on theory given at source:
-
- let PrimeSeive(n : int) =
- let sequence = [|1..n|]
- let isPrime = Array.create n true
- let maxSquareRoot : int = System.Convert.ToInt32(System.Math.Sqrt(float n))
- let candidate = 2;
for i in candidate..maxSquareRoot do,
- if isPrime.[i] then
- let mutable j = i * i
- while j < n - 1 do
- isPrime.[j] <- false
- j <- j + i
-
-
- for index in 0..n - 1 do
- if isPrime.[index] then
- printf "%d, " index
Output:
>PrimeSeive100 ;;
0, 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 99, val it : unit = ()
Here’s the equivalent code in CSharp(C#),
- public static void PrimeSeive(int n)
- {
- bool[] isPrime = newbool[n + 1];
- intmaxSquareRoot = (int) Math.Sqrt(n);
-
- int candidate = 2;
-
-
- for (int ind = 0; ind < isPrime.Length; ind++)
- {
- isPrime[ind] = true;
- }
-
- for (inti = candidate; i < Math.Sqrt(n); i += 1)
- {
- if (isPrime[i])
- for (int j = i * i; j < n; j = j += i)
- {
- isPrime[j] = false;
- }
- }
-
- for (int k = 0; k < n; k++) {
- if (isPrime[k])
- Console.WriteLine(k);
- }
- }
Although the given solution in F# is not the best and not recommended because we’re using much of mutable types like any other imperative language. In upcoming posts, we’ll solve the same problem with immutable types and without using mutable.
Here’s few exercises for you:
What would be the output of below code?
-
- let guessOutput =
- for i in [|9..7..30|] do
- printfn "%d" i
Read more articles on FSharp(F#):