Frage an f#, initialization, arrays – Array-Initialisierung in F #

6

Wie erstelle und initialisiere ich ein Array in F # basierend auf einem bestimmten Datensatztyp? Angenommen, ich möchte ein Array von 100 record1-Datensätzen erstellen.

z.B.

type record1 = {
  value1:string;
  value2:string
}

let myArray = Array.init 100 ?

Aber es scheint, dass die Array.init dies nicht zulässt. Gibt es eine Möglichkeit, dies zu tun?

Bearbeitet, um hinzuzufügen:

Natürlich könnte ich so etwas machen:

let myArray = [|for i in 0..99 -> { value1="x"; value2="y" }|]

Deine Antwort

3   die antwort
11

was Sie brauchen. Ich hoffe es hilft.

type record1 = {
  value1:string;
  value2:string
}

let myArray  = Array.init 100 (fun x -> {value1 = "x"; value2 = "y"})

oder mit Generika

let myArray  = Array.init<record1> 100 (fun x -> {value1 = "x"; value2 = "y"})
Dies ist nicht so effizient wie die Antwort mitArray.create, der nur ein einzelnes Datensatzobjekt erstellen muss, anstatt 100 separate Objekte zu erstellen. Da F # -Datensätze unveränderlich sind, gibt es keine Nachteile, da sich der Wert dieses Objekts niemals ändert. (Siehe meinen Kommentar zumArray.create Antwort für weitere Details.) rmunn
2

anstatt ein Array wie folgt zu erstellen:

// nItems, given n and an item, returns a sequence of item repeated n times
let rec nItems n item = 
  seq {
    match n with
    | n when n > 0 -> yield item; yield! nItems (n - 1) item
    | _ -> ()
  }

type Fnord =
 { foo: int }

printfn "%A" (nItems 99999999 {foo = 3})
// seq [{foo = 3;}; {foo = 3;}; {foo = 3;}; {foo = 3;}; ...]

printfn "%A" (nItems 3 3 |> Seq.toArray)
[|3; 3; 3|]

Das Schöne an der Sequenz ist, dass anstelle eines Arrays Elemente nach Bedarf erstellt werden und nicht alle auf einmal. Und es ist ganz einfach, zwischen Sequenzen und Arrays zu wechseln, wenn dies erforderlich ist.

11

Sie können auch verwendenArray.create, das ein Array mit einer bestimmten Größe erstellt, wobei alle Elemente auf einen definierten Wert initialisiert werden:

let myArray  = Array.create 100 {value1="x"; value2="y"}

Werfen Sie einen Blick auf diese Liste vonArray-Operationen.

@gjvdkamp - Da F # -Datensätze standardmäßig unveränderlich sind, gibt es absolut kein Problem mit einem Array von 100 Elementen, die alle auf denselben Datensatz verweisen, es sei denn, Sie haben einen Datensatz mit veränderlichen Feldern erstellt. (Was normalerweise eine schlechte Idee ist, aus zu vielen Gründen, um auf einen einzelnen Kommentar einzugehen). Wenn Ihr Datensatz unveränderlich ist, lässt Sie der Compiler nicht zumyArray.[5].value1 <- 100; stattdessen würdest du tunmyArray.[5].value1 = { myArray.[5] with value1 = 100 }, wodurch einneues Objekt und weist es dieser Array-Position zu. Sehenfsharpforfunandprofit.com/posts/records für mehr. rmunn
Bist du dir da sicher? Für mich entstand ein Array von 100 Elementen, die alle auf denselben Datensatz verweisen. Wenn ich also myArray. [5] .value1 <- 100 sage, dann würde myArray. [10] .value1 auch 100 zurückgeben, da es nur einen tatsächlichen Datensatz gab (ich vermute). Als ich Array.init 100 verwendet habe (fun x-> {value1 = "x"; value2 = "y"}), hat es wie erwartet funktioniert. gjvdkamp

Verwandte Fragen