Вопрос по initialization, f#, arrays – Инициализация массива в F #

6

Как мне создать и инициализировать массив в F # на основе данного типа записи? Предположим, я хочу создать массив из 100 записей1 записей.

например

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

let myArray = Array.init 100 ?

Но, похоже, Array.init этого не позволяет, есть ли способ сделать это?

Отредактировано, чтобы добавить:

Конечно, я мог бы сделать что-то вроде этого:

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

Ваш Ответ

3   ответа
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|]

Преимущество последовательности вместо массива в том, что он создает элементы по мере необходимости, а не все сразу. И при необходимости легко переходить назад и вперед между последовательностями и массивами.

11

Вы также можете использоватьArray.create, который создает массив заданного размера со всеми его элементами, инициализированными к определенному значению:

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

Посмотрите на этот списокоперации с массивами.

Вы в этом уверены? Для меня это создало массив из 100 элементов, каждый из которых указывает на одну и ту же запись. Поэтому, если я скажу myArray. [5] .value1 & lt; - 100, то myArray. [10] .value1 также вернет 100, потому что была только одна фактическая запись (я подозреваю). Когда я использовал Array.init 100 (fun x-> {value1 = & quot; x & quot ;; value2 = & quot; y & quot;}), он работал как положено.
@gjvdkamp - за исключением того, что по умолчанию записи F # являются неизменяемыми, нет никаких проблем с массивом из 100 элементов, указывающих на одну и ту же запись, если только вы не создали запись с изменяемыми полями. (Это, как правило, плохая идея, по слишком многим причинам, которую нужно упомянуть в одном комментарии). Если ваша запись неизменна, компилятор не позволит вам сделатьmyArray.[5].value1 <- 100; вместо этого вы будете делатьmyArray.[5].value1 = { myArray.[5] with value1 = 100 }, который создаетnew object и присваивает его этой позиции массива. Увидетьfsharpforfunandprofit.com/posts/records для большего.
11

Это должно делать то, что вам нужно. Надеюсь, поможет.

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

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

или используя Generics

let myArray  = Array.init<record1> 100 (fun x -> {value1 = "x"; value2 = "y"})
Это не так эффективно, как ответ, используяArray.create, который должен создать только один объект записи вместо создания 100 отдельных объектов. Поскольку записи F # являются неизменяемыми, недостатков не существует, поскольку значение этого объекта никогда не изменится. (Смотрите мой комментарий наArray.create ответь для более подробной информации.)

Похожие вопросы