2009-07-12 13 views
6

¿Cómo creo e inicializo una matriz en F # según un tipo de registro dado? Supongamos que quiero crear una matriz de 100 registros1.Inicialización de la matriz en F #

p. Ej.

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

let myArray = Array.init 100 ? 

Pero parece que el Array.init no permite esto, hay una manera de hacer esto?

Editado para añadir:

Por supuesto que podría hacer algo como esto:

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

Respuesta

11

Esto debería hacer lo que tiene. Espero eso ayude.

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

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

o el uso de medicamentos genéricos

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

Esto no es tan eficiente como la respuesta usando 'Array.create', que solo tiene que crear un solo objeto de registro en lugar de crear 100 objetos separados. Como los registros F # son inmutables, no hay inconvenientes ya que el valor de ese objeto nunca cambiará. (Vea mi comentario en la respuesta 'Array.create' para más detalles.) – rmunn

11

Se puede utilizar también Array.create, lo que crea una matriz de un tamaño determinado, con todos sus elementos inicializados a un valor definido:

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

Dar un vistazo a esta lista de array operations.

+3

¿Está seguro de esto? Para mí, esto creó una matriz de 100 elementos, todos apuntando al mismo registro. Entonces, si digo myArray. [5] .value1 <- 100, entonces myArray. [10] .value1 también devolvería 100 porque solo había un registro real (sospecho). Cuando utilicé Array.init 100 (fun x-> {value1 = "x"; value2 = "y"}) funcionó como se esperaba. – gjvdkamp

+1

@gjvdkamp - Excepto que dado que los registros F # son inmutables por defecto, no hay absolutamente ningún problema con una matriz de 100 elementos que apuntan al mismo registro, a menos que haya creado un registro con campos mutables. (Que generalmente es una mala idea, por muchas razones para entrar en un solo comentario). Si su registro es inmutable, el compilador no le permitirá hacer 'myArray. [5] .value1 <- 100'; en su lugar, estarías haciendo 'myArray. [5] .value1 = {myArray. [5] con value1 = 100} ', que crea un * objeto nuevo * y lo asigna a esa posición de la matriz. Consulte https://fsharpforfunandprofit.com/posts/records/ para obtener más información. – rmunn

2

o puede crear una secuencia, en lugar de crear una matriz, como esto:

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

Lo bueno de la secuencia, en lugar de una matriz, es que crea artículos a medida que los necesita, en vez que todo a la vez. Y es simple ir y venir entre secuencias y matrices si es necesario.

Cuestiones relacionadas