Today's post is about Arrays and Indexers in F#. Here below you will find a very easy to follow program, that demonstrate arrays and indexer, by implementing some simple tasks that will make you grasp the idea of those 2 features real quick. The main goal of this post, is not really teaching arrays because, come on, you probably already know "all" about them, in fact, it is more to show you how you do that in F#, in this case, compared to all other 22 languages on future posts, which essentially, is the real aim behind this blog.
By the way, if you missed my most recent post, "New Series - Arrays and Indexers", check it out. It has more details about the following program, and a bunch of definitions for the concepts used on this, and the following, posts. Or you can check my previous posts about arrays in C# and C++ just to compare.
I encourage you to copy the code below and try it yourself, normally, all programs you find in this blog are source code complete, just paste it on your IDE and run it.
There is room for improvement of the code, using generics is one example, but Generics, Collections, lambdas, etc. will have their own "series" of posts.
WARNING! I know that F# is intended to be use in a Functional way, however, my goal is to show its Imperative and OO language features, so it can be compared with other OO languages. Said that, if you know how to do something on the examples below on a Functional way, you are welcome to add them as a comment :)
open System
open System.Text
module FsArrays =
type Alphabet public (size: int) as this = class
// Array Field
[<DefaultValue>]
val mutable private letters: char array
do this.letters <- Array.create size ' '
// Indexer Get/Set Property
member public this.Item
with get(index) =
this.letters.[index]
and set index value =
this.letters.[index] <- value.ToString().ToUpper().[0]
// Read-only Property
member public this.Length
with get() = this.letters.Length
// Constructors
new() = new Alphabet(0)
new(l: string) as this = new Alphabet(l.Length) then
this.letters <- l.ToUpper().ToCharArray()
new(l: char[]) as this = new Alphabet(0) then
this.letters <- l
// Overridden Method
override this.ToString() =
String.Join(",", [|for c in this.letters -> c.ToString()|])
// Method
member public this.Slice(start: int, length: int): char[] =
this.letters.[start .. start + length - 1]
end
let ReverseChar (arr: char array) : char array =
Array.rev arr
let BubbleSortInt (arr: int array) =
let mutable swap = 0
for i in Array.rev(arr) do
for j in 0 .. arr.Length - 2 do
if arr.[j] > arr.[j + 1] then
swap <- arr.[j]
arr.[j] <- arr.[j + 1]
arr.[j + 1] <- swap
arr
let BubbleSortString (arr: string array) =
let mutable swap = ""
for i in Array.rev(arr) do
for j in 0 .. arr.Length - 2 do
if arr.[j].[0] > arr.[j + 1].[0] then
swap <- arr.[j]
arr.[j] <- arr.[j + 1]
arr.[j + 1] <- swap
arr
let TransposeMatrix(m: int[,]): int[,] =
(* Transposing a Matrix 2,3
*
* A = [6 4 24]T [ 6 1]
* [1 -9 8] [ 4 -9]
* [24 8]
*)
let transposed = Array2D.zeroCreate<int> (m.GetLength 1) (m.GetLength 0)
for i in 0 .. m.GetLength 0 - 1 do
for j in 0 .. m.GetLength 1 - 1 do
transposed.[j, i] <- m.[i, j]
transposed;
let UpperCaseRandomArray (arr: string[][]) =
let r = new System.Random()
let i = r.Next (arr.Length - 1)
for j in 0 .. arr.[i].Length - 1 do
arr.[i].[j] <- arr.[i].[j].ToUpper()
let PrintArrayChar (arr: char array) =
printfn "\nPrint Array Content %s"
(arr.GetType().Name.Replace("]", arr.Length.ToString() + "]"))
for i in 0 .. arr.Length - 1 do
printfn " array [%2i] = %2c" i arr.[i]
let PrintArrayInt (arr: int array) =
printfn "\nPrint Array Content %s"
(arr.GetType().Name.Replace("]", arr.Length.ToString() + "]"))
for i in 0 .. arr.Length - 1 do
printfn " array [%2i] = %2i" i arr.[i]
let PrintArrayString (arr: string array) =
printfn "\nPrint Array Content %s"
(arr.GetType().Name.Replace("]", arr.Length.ToString() + "]"))
for i in 0 .. arr.Length - 1 do
printfn " array [%2i] = %2s" i arr.[i]
let PrintMatrix (m: int[,]) =
printfn "\nPrint Matrix Content %s[%i,%i]"
(m.GetType().Name.Replace("[,]", "")) (m.GetLength 0) (m.GetLength 1)
for i in 0 .. m.GetLength 0 - 1 do
for j in 0 .. m.GetLength 1 - 1 do
printfn " array [%2i,%2i] = %2i " i j m.[i, j]
let GraphJaggedArray (arr: string[][]) =
(* When using Arrays, we can use foreach instead of for + index:
*
* for i in 0 .. m.GetLength 0 - 1 do
* for j in 0 .. m.GetLength 1 - 1 do
*
*)
printfn "\nPrint Matrix Content %s" (arr.GetType().Name)
let mutable lineCount = 1
for s in arr do
printf "Line%2i|" lineCount
for w in s do
printf "%3c" '*'
printfn " (%i)" (s.Length)
lineCount <- lineCount + 1
let PrintJaggedArray (arr: string[][]) =
printfn "\nPrint Jagged Array Content %s" (arr.GetType().Name)
for i in 0 .. arr.Length - 1 do
let line = new StringBuilder()
for j in 0 .. arr.[i].Length - 1 do
line.Append (" " + arr.[i].[j]) |> ignore
if line.ToString() = line.ToString().ToUpper() then
line.Append " <-- [UPPERCASED]" |> ignore
printfn "%s" (line.ToString())
let PrintTitle (message: string) =
printfn "\n"
printfn "%s" ([|for i in 0..54 -> "*"|] |> String.concat "")
printfn "%s" message
printfn "%s" ([|for i in 0..54 -> "*"|] |> String.concat "")
let PrintCommonArrayExceptions (arr: string[][]) =
try
arr.[100].[100] <- "hola"
with
(*
| :? IndexOutOfRangeException as ex ->
| _ as ex ->
*)
| ex ->
printfn "\nException: \n%s\n%s" (ex.GetType().Name) (ex.Message)
[<EntryPoint>]
let main argv =
// Single-dimensional Array(s)
PrintTitle "Reverse Array Elements"
// Declare and Initialize Array of Chars
let letters: char array = Array.create 5 ' '
letters.[0] <- 'A'
letters.[1] <- 'E'
letters.[2] <- 'I'
letters.[3] <- 'O'
letters.[4] <- 'U'
PrintArrayChar letters
let inverse_letters = ReverseChar letters
PrintArrayChar inverse_letters
PrintTitle "Sort Integer Array Elements"
// Declare and Initialize Array of Integers
let numbers = [| 10; 8; 3; 1; 5 |]
PrintArrayInt numbers
let ordered_numbers = BubbleSortInt numbers
PrintArrayInt ordered_numbers
PrintTitle "Sort String Array Elements"
// Declare and Initialize and Array of Strings
let names : string array = [|"Damian";
"Rogelio";
"Carlos";
"Luis";
"Daniel"|]
PrintArrayString names
let ordered_names = BubbleSortString names
PrintArrayString ordered_names
// Multi-dimensional Array (Matrix row,column)
PrintTitle "Transpose Matrix"
// let matrix = Array2D.zeroCreate<int> 2 3
let matrix = array2D [|[|6; 4; 24|];
[|1; -9; 8|]|]
PrintMatrix matrix
let transposed_matrix = TransposeMatrix matrix
PrintMatrix transposed_matrix
// Jagged Array (Array-of-Arrays)
PrintTitle "Upper Case Random Array & Graph Number of Elements"
(*
* Creating an array of string arrays using the String.Split method
* instead of initializing it manually as follows:
*
* let text: string[][] = [|
* [| "word1"; "word2"; "wordN" |];
* [| "word1"; "word2"; "wordM" |];
* ...
* |]
*
* Text extract from: "El ingenioso hidalgo don Quijote de la Mancha"
*
*)
let mutable text = [|
"Hoy es el dÃa más hermoso de nuestra vida, querido Sancho;".Split ' ';
"los obstáculos más grandes, nuestras propias indecisiones;".Split ' ';
"nuestro enemigo más fuerte, miedo al poderoso y nosotros mismos;".Split ' ';
"la cosa más fácil, equivocarnos;".Split ' ';
"la más destructiva, la mentira y el egoÃsmo;".Split ' ';
"la peor derrota, el desaliento;".Split ' ';
"los defectos más peligrosos, la soberbia y el rencor;".Split ' ';
"las sensaciones más gratas, la buena conciencia...".Split ' '
|]
PrintJaggedArray text
UpperCaseRandomArray text
PrintJaggedArray text
GraphJaggedArray text
// Array Exceptions
PrintTitle "Common Array Exceptions"
PrintCommonArrayExceptions null
PrintCommonArrayExceptions text
// Accessing Class Array Elements through Indexer
PrintTitle "Alphabets"
let vowels = new Alphabet(5)
vowels.[0] <- 'a'
vowels.[1] <- 'e'
vowels.[2] <- 'i'
vowels.[3] <- 'o'
vowels.[4] <- 'u'
printfn "\nVowels = {%s}" (String.Join(",", [|vowels.[0].ToString(); vowels.[1].ToString(); vowels.[2].ToString(); vowels.[3].ToString(); vowels.[4].ToString()|]))
let en = new Alphabet("abcdefghijklmnopqrstuvwxyz")
printfn "English Alphabet = {%s}" (en.ToString())
let x = new Alphabet(en.Slice(9, 10))
printfn "Alphabet Extract en[9..19] = {%s}" (x.ToString())
let word1 = String.Join("", [|en.[6].ToString(); en.[14].ToString(); en.[14].ToString(); en.[3].ToString()|])
let word2 = String.Join("", [|en.[1].ToString(); en.[24].ToString(); en.[4].ToString()|])
let word3 = String.Join("", [|en.[4].ToString(); en.[21].ToString(); en.[4].ToString(); en.[17].ToString(); en.[24].ToString(); en.[14].ToString(); en.[13].ToString(); en.[4].ToString()|])
printfn "\n%s %s, %s!\n" word1 word2 word3
Console.Read() |> ignore
0 // Return
The output:
Voilà, that's it. Next post in the following days.

No comments:
Post a Comment