John
John

Reputation: 579

F# Initialize 2D string array

So, I've got a simple structure that just includes a multidimensional array of strings, which looks like so

type Structure = 
     struct
      val mutable SubText: string[][]
     end 

In another function we have something like this:

let mutable Struct : Structure = new Structure()

let stringArray = [| "string1"; "string2"; "string3" |]
Struct.SubText.[0] <- stringArray

But whenever the program reaches this part we get a NullReferenceException

I'm wondering how I can fix this, thank you. I did see another question asking nearly the same thing, but that was to do with 2d int arrays, NOT strings

Upvotes: 1

Views: 535

Answers (2)

Gene Belitski
Gene Belitski

Reputation: 10350

When an instance of Struct is constructed by the default no-argument struct constructor the structure field SubText representing the jugged array of string stays uninitialized, so the indexer Struct.SubText.[0] gets applied to null value, that's why the exception has been thrown.

You may easily fix this by adding to the default no-arg struct constructor some extra explicit constructor(s) that initialize SubText upon instance construction:

type Structure = 
    struct
        val mutable SubText: string[][]
    end
    new(size) = {SubText = Array.zeroCreate size} // to array of given number of string arrays
    new(_) = {SubText = [|[||]|]} // to array of single empty string array

Now you may use such constructors as below, the field SubText gets initialized upon instance construction and indexer can be used OK:

let Struct = new Structure(2) // or just let Struct = new Structure(())
let stringArray = [| "string1"; "string2"; "string3" |]
Struct.SubText.[0] <- stringArray
//Checking out in FSI:
//>Struct.SubText.[0];;
//val it : string [] = [|"string1"; "string2"; "string3"|]

As SubText is chosen to be mutable it can be any time changed to another jugged array of any number of subarrays, not necessarily of initial size.

Upvotes: 1

Sehnsucht
Sehnsucht

Reputation: 5049

You're trying to set the first item of the outer array but at this point your array of arrays is still null ; hence the exception.

I don't really understand where you're going with all those mutable and arrays so just a quick workaround to fix the code :

let mutable Struct = Structure ()

let stringArray = [| "string1"; "string2"; "string3" |]
Struct.SubText <- [| stringArray |]

I just set the whole outer array to an array containing yours you could also do a 2-step process for example

let mutable Struct = Structure ()

let stringArray = [| "string1"; "string2"; "string3" |]
Struct.SubText <- Array.zeroCreate 5
// now SubText.[0] exists
Struct.SubText.[0] <- stringArray

// > Struct.SubText;;
// val it : string [] [] = [|[|"string1"; "string2"; "string3"|]; null; null; null; null|]

Upvotes: 2

Related Questions