F# Arrays

F# arrays are mutable, which means that they can be updated as well as resized as desired, although doing so is less efficient than creating a whole new array from scratch.

In this article, you will learn the use of F# arrays. This includes creating arrays, initializing arrays, accessing and modifying array elements, iterating over arrays with loops and higher-order functions, as well as using array-related functions in the standard library, among other things.



Creating An F# Array

There are different syntaxes and techniques you can use to create arrays and you can use the functions from the Array module to do this.

Here, we will discuss how to create arrays without having to use the functions from the module in this section.

Arrays can be created in three different ways, depending on their syntactical structure:

  • In order to list consecutive values, the values should be separated by semicolons between [| and |].
  • Alternatively, you can put each element on a separate line, in which case the semicolon separator is not necessary.
  • This can be achieved by using sequence expressions.

A dot operator (.) as well as brackets ([ and ]) is used to access the elements of an array.

The following example shows you how to create F# arrays:

Example: 

//using semicolon separator let arr1 = [| 1; 3; 5; 7; 9; 11 |] for i in 0 .. arr1.Length – 1 do printf "%d " arr1.[i] printfn" "// without semicolon separator let arr2 = [| 1 3 5 7 9 11 |] for i in 0 .. arr2.Length – 1 do printf "%d " arr2.[i] printfn" "//using sequence let arr3 = [| for i in 1 .. 10 -> i * i |] for i in 0 .. arr3.Length – 1 do printf "%d " arr3.[i] printfn" "

F# Arrays


Basic Operations on Arrays

One-dimensional arrays can be operated on using the library module Microsoft.FSharp.Collections.Array in Microsoft FSharp.

Arrays can be used in a variety of ways, as shown in the following table:

ValueOverview
append : ‘T [] → ‘T [] → ‘T []An array is created by separating the elements of the first array by those of the second array at the beginning of the array.
average : ^T [] → ^TThe average of each element in an array is returned as the result.
averageBy : (‘T → ^U) → ‘T [] → ^UThis function calculates the average of all the elements of an array that are generated as a result of applying a function to every single element.
blit : ‘T [] → int → ‘T [] → int → int → unitThis method is used to read a range of elements from one array and write them into another
choose : (‘T → U option) → ‘T [] → ‘U []The function is applied to each element of an array according to a supplied function. This function returns an array which contains the values x for each element for which the function returns Some(x).
collect : (‘T → ‘U []) → T [] → ‘U []A function is applied to each element of an array, the results are concatenated, and the result is returned as the combined of all the elements in the array.
concat : seq<‘T []> → ‘T []In this function, a sequence of arrays is created, and each array contains the elements of the previous arrays in the sequence.
copy : ‘T → ‘T []The function returns an array containing the elements found in the array that has been supplied.
create : int → ‘T → ‘T []A new array is created with the elements all being the same as the value supplied at the beginning.
empty : ‘T []This method returns an empty array of the type given in the argument.
exists : (‘T → bool) → ‘T [] → boolThis function checks whether the provided predicate is satisfied by any element in an array.
exists2 : (‘T1 → ‘T2 → bool) → ‘T1 [] → ‘T2 [] → boolThis function determines whether two arrays with corresponding elements satisfy the supplied conditions.
fill : ‘T [] → int → int → ‘T → unitThis method uses the supplied value to fill a range of elements in an array.
filter : (‘T → bool) → ‘T [] → ‘T []A collection will be returned that contains only those elements of the supplied array that are true when the provided condition is met.
find : (‘T → bool) → ‘T [] → ‘TThe function returns the first element for which a true value is returned by the function supplied. The KeyNotFoundException is raised if there are no elements matching the search criteria.
findIndex : (‘T → bool) → ‘T [] → intAn array whose first element satisfies the supplied condition will be indexed by the index of the first element in the array. When no elements satisfy the condition, this method raises a KeyNotFoundException.
fold : (‘State → ‘T → ‘State) → ‘State → ‘T [] → ‘StateThis function threads an accumulator argument through each element of the collection. It applies the function to the second argument and the first element of the array. This result will then be passed by the program along with the second element, and the process will continue in this way. It then returns the final result. A function f is given, and the elements are i0…iN, so this function computes f (… (f s i0) i1 …) iN.
fold2 : (‘State → ‘T1 → ‘T2 → ‘State) → ‘State → ‘T1 [] → ‘T2 [] → ‘StateThis function applies a function to the elements of two collections that correspond to each other, and threads an accumulator argument through the computation as well. There must be identical collections. Using i0…iN and j0…jN as input functions, this function computes f (… (f s i0 j0)…) iN jN.
foldBack : (‘T → ‘State → ‘State) → ‘T [] → ‘State → ‘StateThis function applies a function to every element in the collection, through which an accumulator argument is passed through the computation for each element. A function f is passed as an input, and the input elements i0…iN are passed as input which computes f i0 (…(f iN s)).
foldBack2 : (‘T1 → ‘T2 → ‘State → ‘State) → ‘T1 [] → ‘T2 [] → ‘State → ‘StateIn this function, an element of two collections is threaded through the computation and a function reference is passed as an argument. Collections must be identical. A function f is passed to this function and if the elements in each case are i0…iN and j0…jN, then this function will compute the value of f i0 j0 (…(f iN jN s )).
forall : (‘T → bool) → ‘T [] → boolThis function checks if all elements satisfy the given predicate in the collection.
forall2 : (‘T1 → ‘T2 → bool) → ‘T1 [] → ‘T2 [] → boolIdentifies whether all elements corresponding to the given predicate are satisfied pairwise in the collection.
get : ‘T [] → int → ‘TA function that returns an element from an array.
init : int → (int → ‘T) → ‘T []It creates an array of a specified dimension using a function provided by the user.
isEmpty : ‘T [] → boolThis function determines whether there are any elements in an array.
iter : (‘T → unit) → ‘T [] → unitEach element in the array is applied to the function supplied by the user.
iter2 : (‘T1 → ‘T2 → unit) → ‘T1 [] → ‘T2 [] → unit)A pair of elements is applied to the supplied function using matching indexes in two arrays to obtain a pair of elements. If the lengths of the two arrays do not match each other, then ArgumentException will be raised as a result.
iteri : (int → ‘T → unit) → ‘T [] → unitAn array is used to apply the supplied function to each element in the array. This integer indicates the index of the element in the array that has been passed to the function.
iteri2 : (int → ‘T1 → ‘T2 → unit) → ‘T1 [] → ‘T2 [] → unitA pair of elements from two arrays containing matching indexes are applied to a pair of elements by applying the supplied function, passing the index of the elements as well. There should be a match between the length of the two arrays; otherwise, an ArgumentException will be thrown.
length : ‘T [] → intA length function returns the number of elements in an array. Similarly, the Length property has the same function.
map : (‘T → ‘U) → ‘T [] → ‘U []Applying the supplied function to each element of a provided array creates an array whose elements are the results.
map2 : (‘T1 → ‘T2 → ‘U) → ‘T1 [] → ‘T2 [] → ‘U []This function creates a new array which contains the elements that have been obtained from applying the supplied function to the corresponding elements of the two arrays supplied. There must be the same length in both input arrays; otherwise, ArgumentException will be thrown.
mapi : (int → ‘T → ‘U) → ‘T [] → ‘U []Provides a function for creating an array whose elements are the results of the application of the function supplied to each element of a supplied array to produce results. Using an integer index as an input, the function is able to determine the index of the element being transformed by the passing of an integer.
mapi2 : (int → ‘T1 → ‘T2 → ‘U) → ‘T1 [] → ‘T2 [] → ‘U []As part of this function, the array is created by applying the supplied function to the respective elements of the two collections pairwise, and then passing the corresponding element’s index to the function as well. There must be a match between the sizes of the two input arrays; otherwise, ArgumentException is thrown.
max : ‘T [] → ‘TThis function returns the largest element in an array out of all the elements in the array. To compare the elements, operator.max is used as a comparison function.
maxBy : (‘T → ‘U) → ‘T [] → ‘TThe function returns the greatest element in the array among all the elements of the array, comparing the result of the function with its Operators.max method.
min : (‘T [] → ‘TThis function returns the lowest element in an array, compared using Operators.min as a comparison method.
minBy : (‘T → ‘U) → ‘T [] → ‘TUsing Operators.min on the result of the function, this function returns the lowest element within all the elements of the array
ofList : ‘T list → ‘T []This function creates an array based on the list that has been provided.
ofSeq : seq<‘T> → ‘T []Arrays are created from enumerable objects that are provided by the user.
partition : (‘T → bool) → ‘T [] → ‘T [] * ‘T []There are two arrays in this function, one that contains the elements that are true when the supplied condition is satisfied, and the other that contains the elements that are false when the supplied condition is satisfied.
permute : (int → int) → ‘T [] → ‘T []The permutation method works by permuting the elements in an array in accordance with the specified permutation.
pick : (‘T → ‘U option) → ‘T [] → ‘UUsing the supplied function, successive elements of a provided array will be passed through the function, and the first result that is returned will be Some(x) for some x. It is raised a KeyNotFoundException if the function never returns Some(x) as part of its return value.
reduce : (‘T → ‘T → ‘T) → ‘T [] → ‘TThis method threads an accumulator argument through each element of an array in order to perform a computation for each element. The function computes f (…(f i0 i1)…) iN based on the input function f and the array elements i0…iN in the array. There will be an ArgumentException thrown if the array has a size of zero.
reduceBack : (‘T → ‘T → ‘T) → ‘T [] → ‘TUsing an accumulator argument, threads a function through each element in an array. The function computes f i0 (…(f iN-1 iN)) if the input function f is given and the elements are i0…iN. This raises an ArgumentException if the array is zero in size.
rev : ‘T [] → ‘T []A function that reverses the order in which the elements of an array are displayed.
scan : (‘State → ‘T → ‘State) → ‘State → ‘T [] → ‘State [])This function behaves similar to fold, but rather than returning only the final results, it also returns the intermediate results.
scanBack : (‘T → ‘State → ‘State) → ‘T [] → ‘State → ‘State []This function behaves similarly to foldBack, except that it also returns the intermediate results along with the final results.
set : ‘T [] → int → ‘T → unitA set element is used to set an element in an array.
sort : ‘T[] → ‘T []Returns a new array containing the elements of the array that were sorted. The elements can be compared using the operators.compare function.
sortBy : (‘T → ‘Key) → ‘T [] → ‘T []Using the supplied function, sort the elements of the array by transforming the elements into the type on which the sort operation is based, and return a new array containing the items of the array. The elements in the array are compared using the operator operators.compare.
sortInPlace : ‘T [] → unitBy using the supplied comparison function, the data elements in an array are sorted by changing the array in place while the array is being changed. A comparison is performed between the elements using the operator operators.compare.
sortInPlaceBy : (‘T → ‘Key) → ‘T [] → unitAssigns keys to the elements in an array, using the supplied key projection, in order to sort the array elements in place. Using the operator compare, the elements are compared using the operator operators.compare.
sortInPlaceWith : (‘T → ‘T → int) → ‘T [] → unitBy using the comparison function provided with the array, it is possible to sort the elements in the array by swapping the elements in place.
sortWith : (‘T → ‘T → int) → ‘T [] → ‘T []This function performs the sorting of an array using the comparison function supplied, and returns a new array which contains the sorted elements.
sub : ‘T [] → int → int → ‘T []This function returns a string array containing the full length and starting index of the supplied subrange that is specified by the starting index.
sum : ‘T [] → ^TArray elements are added up to get the sum of their values.
sumBy : (‘T → ^U) → ‘T [] → ^UAn array in which each element is treated as an individual element is summed up by applying a function to each element in the array.
toList : ‘T [] → ‘T listThe function converts F# array supplied to a list of elements.
toSeq : ‘T [] → seq<‘T>The supplied array is viewed in the form of a sequence.
tryFind : (‘T → bool) → ‘T [] → ‘T optionFor the supplied array, returns the first element for which true is returned by the supplied function. If there is no such element, it returns None.
tryFindIndex : (‘T → bool) → ‘T [] → int optionSpecifies a condition based on which to return the index of the first element in an array.
tryPick : (‘T → ‘U option) → ‘T [] → ‘U optionUsing the supplied function, the first result is returned when the function is applied to successive elements of the supplied array and returns Some(x) for some x when the supplied function returns Some(x). The function returns None if it does not ever return Some(x).
unzip : (‘T1 * ‘T2) [] → ‘T1 [] * ‘T2 []This function allows you to split an array of tuple pairs into two arrays of tuples.
unzip3 : (‘T1 * ‘T2 * ‘T3) [] → ‘T1 [] * ‘T2 [] * ‘T3 []The split function splits a tuple of three elements into a tuple of three arrays based on each element of the tuple.
zeroCreate : int → ‘T []Arrays are created by setting their elements as default values. Using the following example, we have set Unchecked.defaultof <T>.
zip : ‘T1 [] → ‘T2 [] → (‘T1 * ‘T2) []The purpose of this function is to create an array of pairs from the two arrays that have been combined. The length of the two arrays must be equal between them.
zip3 : ‘T1 [] → ‘T2 [] → ‘T3 [] → (‘T1 * ‘T2 * 113 ‘T3) []A tuple is an array of three elements that has been created by the combination of three arrays. It must be ensured that the lengths of the three arrays are equal; otherwise, ArgumentException will be raised.

In the following section, you will discover how to use some of these features in practical scenarios, as we delve into examples that showcase their capabilities.


F# Array Functions

A number of functions are provided by the Array module to allow the creation of arrays from scratch.

  • A new empty array can be created by using the Array.empty function.
  • With the Array.create function, you can create an array of a certain size and set all the elements in the array to a specified value.
  • An array can be created by calling the Array.init function, which takes as input a dimension and a function that generates the elements in the array.
  • By using the Array.zeroCreate function, you can create an array whose elements are all initialized to zero at the time of creation.
  • There is a function Array.copy that is used in order to create a new array that contains elements that have been copied from an existing array.
  • Array.sub is a function that creates a new array from a subrange of an array, which can be selected by the user.
  • In the Array.append function, two arrays are combined to form one new array by adding new elements to them.
  • An array can be chosen to include elements in a new array by using the Array.choose function.
  • When the Array.collect function is run on each element of an existing array, a specification of the function is run on each element of the array, after which the elements generated by the function are gathered and a new array will be created.
  • In the Array.concat function, we combine a sequence of arrays into one array by taking a sequence of arrays and combining them together.
  • Array.filter is a function that will remove the elements from an array that are not present in the input array if a Boolean condition is met. The result will be an array with just those elements from the input array that are present in the input array.
  • A new array can be generated by reversing the order of an existing array with the help of the Array.rev function.

These functions are demonstrated in the following examples.

Here is an example of how to create an array using the above functions:

Example: 

// Array.empty let emptyArray = Array.empty // creates an empty array of any type printfn "Empty Array.empty: %A" emptyArray// Array.create let newArray = Array.create 5 2 // creates a new array of length 5 with default value 2 printfn "By using Array.create: %A" newArray// Array.init let squares = Array.init 5 (fun i -> i * i) // creates an array of the first 5 squares printfn "By using Array.init: %A" squares// Array.copy let originalArray = [|1; 2; 3|] let copyArray = Array.copy originalArray // creates a copy of the original array printfn "By using Array.copy: %A" copyArray// Array.sub let subArray = Array.sub originalArray 1 2 // creates a sub-array from the original array, starting at index 1 and containing 2 elements printfn "By using Array.sub: %A" subArray// Array.append let firstArray = [|1; 2|] let secondArray = [|3; 4|] let combinedArray = Array.append firstArray secondArray // creates a new array by combining the two input arrays printfn "By using Array.append: %A" combinedArray

Output:

Empty Array.empty:
By using Array.create: 2,2,2,2,2
By using Array.init: 0,1,4,9,16
By using Array.copy: 1,2,3
By using Array.sub: 2,3
By using Array.append: 1,2,3,4

Some more examples of the array function are:

Example: 

// Array.choose let inputArray = [|1; 2; 3; 4; 5;|] let outputArray = Array.choose (fun x -> if x % 2 = 0 then Some x else None) inputArray // creates a new array by selecting only the even numbers from the input array printfn "By using Array.choose: %A" outputArray// Array.collect let nestedArray = [| [|1; 2|]; [|3; 4|] |] let flatArray = Array.collect (fun x -> x) nestedArray // creates a new array by flattening the nested array into a single-dimensional array printfn "By using Array.collect%A" flatArray// Array.concat let arraysToConcat = [| [|1; 2|]; [|3; 4|]; [|5; 6|] |] let concatenatedArray = Array.concat arraysToConcat // creates a new array by concatenating all of the input arrays into a single-dimensional array printfn "By using Array.concat: %A" concatenatedArray// Array.filter let filteredArray = Array.filter (fun x -> x % 2 = 0) inputArray // creates a new array by selecting only the even numbers from the input array printfn "By using Array.filter: %A" filteredArray// Array.rev let reversedArray = Array.rev inputArray // creates a new array with the elements in reverse order printfn "By using Array.rev: %A" reversedArray

And the output will be as follows:

By using Array.choose: 2,4
By using Array.collect1,2,3,4
By using Array.concat: 1,2,3,4,5,6
By using Array.filter: 2,4
By using Array.rev: 5,4,3,2,1

Example Explanation

This code uses the Array.choose function to create a new array called outputArray by selecting only the even numbers from the input array inputArray. The function passed to Array.choose takes an element from the input array and returns an option type. Some x is returned for even numbers and None is returned for odd numbers. The resulting outputArray contains only the elements for which Some x was returned, which are even numbers in this case. Finally, the printfn function prints out the resulting outputArray.

This code uses the Array.collect function to create a new array called flatArray by flattening the nested array nestedArray into a single-dimensional array. The function passed to Array.collect takes an element from the input array, which is a sub-array in this case, and returns that sub-array itself. The resulting flatArray contains all of the elements from each sub-array concatenated together into a single-dimensional array. Finally, the printfn function prints out the resulting flatArray.

This code uses the Array.concat function to create a new array called concatenatedArray by concatenating all of the input arrays and arraysToConcat into a single-dimensional array. The resulting concatenatedArray contains all of the elements from each input array concatenated together in order. Finally, the printfn function prints out the resulting concatenatedArray.

This code uses the Array.filter function to create a new array called filteredArray by selecting only the even numbers from the input array inputArray. The function passed to Array.filter takes an element from the input array and returns true if it should be included in the resulting array. It returns false if it should be excluded. In this case, only the even numbers pass this filter and are included in the resulting filteredArray. Finally, the printfn function prints out the resulting filteredArray.


Searching Arrays In F#

When you pass a Boolean function to the Array.find function, it returns the first element that satisfies the condition specified by the function. If the function returns false for all elements, a KeyNotFoundException is thrown.

To make this process more efficient, you can use the Array.findIndex function, which works similarly to Array.find, but returns the index of the first element that satisfies the condition.

Here’s an example to illustrate how to use these functions:

Microsoft provides an interesting example program that demonstrates how to find the first element within a given range that is both a perfect square and a perfect cube, using Microsoft Visual Basic.

Example: 

let arr = [| 2 .. 100 |] let delta = 1.0e-10 let isPerfectSquare (a:int) = let b = sqrt (float a) abs(b – round b) < deltalet isPerfectCube (a:int) = let b = System.Math.Pow(float a, 1.0/4.0) abs(b – round b) < deltalet element = Array.find (fun elem -> isPerfectSquare elem & isPerfectCube elem) arrlet index = Array.findIndex (fun elem -> isPerfectSquare elem && isPerfectCube elem) arrprintfn "The first element that is both a square and a cube is %d and its index is %d." element index

Output:

The first element that is both a square and a cube is 16 and its index is 14.

Conclusion

F# arrays are a powerful data structure that can be used to store and manipulate collections of values of the same type. With the ability to create, access, modify, and iterate over arrays, F# provides a flexible and efficient tool for working with data. By mastering F# arrays, you can improve your ability to write efficient and effective code.

If you liked this article and found it informative regarding F# Arrays, you can leave your feedback by reacting below.

We value your feedback.
+1
0
+1
0
+1
0
+1
0
+1
0
+1
0
+1
0

Subscribe To Our Newsletter
Enter your email to receive a weekly round-up of our best posts. Learn more!
icon

Leave a Reply

Your email address will not be published. Required fields are marked *