Yesterday I wrote about list in F#. Today I’ll write about arrays, which unlike lists are a mutable flat storage and cannot be resized. That means you have to create a new array if you want to remove or add elements. Advantages include constant look-up time and the fact that they can store a large amount of data.
You can create a literal array in a similar way with the lists, placing the elements between [| |]:
let data1 = [|1;2;3;4|] printfn "data1: %a" output_any data1
data1: [|1; 2; 3; 4|]
The empty literal array is [||].
To create an array you can either use Array.create or Array.init. They both create and initialize an array, but the second makes a lambda expression, which allows advance initialization possibilities. The following creates an array with 10 elements initialized to 1:
let data2 = Array.create 10 1 printfn "data2: %a" output_any data2
Here is the output:
data2: [|1; 1; 1; 1; 1; 1; 1; 1; 1; 1|]
The same can be achieved using Array.init:
let data3 = Array.init 10 (fun x -> 1) printfn "data3: %a" output_any data3
data3: [|1; 1; 1; 1; 1; 1; 1; 1; 1; 1|]
But we can use Array.init to initialize the elements from 1 to N for instance:
let data4 = Array.init 10 (fun x -> x+1) printfn "data4: %a" output_any data4
data4: [|1; 2; 3; 4; 5; 6; 7; 8; 9; 10|]
The arrays are mutable data structures. Elements are accessed with .[] or .(). The following code shows how to set the elements of an array:
let data5 = Array.create 10 0 for i = 0 to (Array.length data5)-1 do data5.[i] <- i+1 printfn "data5: %a" output_any data5
data5: [|1; 2; 3; 4; 5; 6; 7; 8; 9; 10|]
You can iterate over the elements of an array with Array.iter and Array.iteri, the second also providing access to the index of the elements.
data4 |> Array.iter (fun x -> printf "%d " x) printfn "" data4 |> Array.iteri (fun i x -> printfn "data4(%d) = %d" i x)
1 2 3 4 5 6 7 8 9 10 data4(0) = 1 data4(1) = 2 data4(2) = 3 data4(3) = 4 data4(4) = 5 data4(5) = 6 data4(6) = 7 data4(7) = 8 data4(8) = 9 data4(9) = 10
Retrieving the length of the array can either be done with Array.length arr or with arr.Length.
for i = 0 to data4.Length-1 do printfn "data4(%d) = %d" i data4.(i)
data4(0) = 1 data4(1) = 2 data4(2) = 3 data4(3) = 4 data4(4) = 5 data4(5) = 6 data4(6) = 7 data4(7) = 8 data4(8) = 9 data4(9) = 10
Like the lists, arrays provide mapping that creates a new array by applying a function on all the elements of an array (with Array.map) or two arrays (with Array.map2).
let data6 = data4 |> Array.map (fun x -> x*2) printfn "data6: %a" output_any data6 let data7 = Array.map2 (fun x y -> x+y) data4 data6 printfn "data7: %a" output_any data7
data6: [|2; 4; 6; 8; 10; 12; 14; 16; 18; 20|] data7: [|3; 6; 9; 12; 15; 18; 21; 24; 27; 30|]
A copy of an array can be done with Array.copy.
let data7 = Array.copy data6 printfn "data7: %a" output_any data7
data7: [|2; 4; 6; 8; 10; 12; 14; 16; 18; 20|]
Appending elements to an array is also possible with Array.append, but the result is a new array, created by concatenating two arrays.
let data8 = Array.append data7 [|100|] printfn "data8: %a" output_any data8
data8: [|2; 4; 6; 8; 10; 12; 14; 16; 18; 20; 100|]
The last operation of arrays I'm going to mention here is the folding, which allows applying a function to all the elements of an array, threading an accumulator argument in the process. The following example shows how to compute the sum of the elements of an array.
let data9 = [|1;2;3;4|] let sum1 = (Array.fold_left (fun acc x-> x + acc) 0 data9) let sum2 = (Array.fold_right (fun acc x-> x + acc) data9 0) printfn "sum1 = %d" sum1 printfn "sum2 = %d" sum2
sum1 = 10 sum2 = 10













