Pytanie w sprawie initialization, f#, arrays – Inicjalizacja tablicy w F #

6

Jak utworzyć i zainicjować tablicę w F # na podstawie danego typu rekordu? Załóżmy, że chcę utworzyć tablicę 100 rekordów1 rekordu.

na przykład

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

let myArray = Array.init 100 ?

Ale wydaje się, że Array.init na to nie pozwala, czy istnieje sposób, aby to zrobić?

Edytowane, aby dodać:

Oczywiście mogłem zrobić coś takiego:

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

Twoja odpowiedź

3   odpowiedź
11

Możesz również użyćArray.create, który tworzy tablicę o danym rozmiarze, z wszystkimi jej elementami zainicjowanymi do określonej wartości:

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

Spójrz na tę listęoperacje tablicowe.

Jesteś tego pewien? Dla mnie stworzyło to tablicę 100 pozycji, które wskazują na ten sam rekord. Więc jeśli powiem myArray. [5] .value1 <- 100, to myArray. [10] .value1 również zwróci 100, ponieważ był tylko jeden rzeczywisty rekord (podejrzewam). Kiedy użyłem Array.init 100 (fun x-> {value1 = "x"; value2 = "y"}) działało zgodnie z oczekiwaniami. gjvdkamp
@gjvdkamp - Z wyjątkiem tego, że ponieważ rekordy F # są domyślnie niezmienne, nie ma żadnego problemu z tablicą 100 elementów wskazujących na ten sam rekord, chyba że utworzyłeś rekord ze zmiennymi polami. (Zwykle jest to zły pomysł, z powodu zbyt wielu powodów, by w jednym komentarzu wejść). Jeśli Twój rekord jest niezmienny, kompilator ci na to nie pozwolimyArray.[5].value1 <- 100; zamiast tego robiszmyArray.[5].value1 = { myArray.[5] with value1 = 100 }, który tworzynowy obiekt i przypisuje go do tej pozycji tablicy. Widziećfsharpforfunandprofit.com/posts/records po więcej. rmunn
11

czego potrzebujesz. Mam nadzieję, że to pomoże.

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

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

lub używając Generics

let myArray  = Array.init<record1> 100 (fun x -> {value1 = "x"; value2 = "y"})
To nie jest tak skuteczne, jak użycie odpowiedziArray.create, który musi utworzyć tylko jeden obiekt rekordu zamiast tworzyć 100 oddzielnych obiektów. Ponieważ rekordy F # są niezmienne, nie ma żadnych wad, ponieważ wartość tego obiektu nigdy się nie zmieni. (Zobacz mój komentarz na tematArray.create odpowiedz po więcej szczegółów.) rmunn
2

// 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|]

Dobrą rzeczą w sekwencji, a nie w tablicy, jest to, że tworzy elementy tak, jak ich potrzebujesz, a nie wszystkie naraz. I w razie potrzeby łatwo jest przechodzić między sekwencjami i tablicami.

Powiązane pytania