заполнение списка> с f # - PullRequest
       2

заполнение списка> с f #

2 голосов
/ 04 декабря 2011

Мне нужна функция, которая возвращает List >.Значение ij должно быть 1,0 или 2,0 или ничего .. в зависимости от определенных условий (condition_1_is_true ...).

Я написал следующее:

type T = 
  {
     value : float32
  }
let level_1_docked_balls : List<List<T>>=
    [ for i in 0 .. LineNumber - 1->
        [ for j  in 0 .. BallsPerLine - 1 ->

            if (condition_1_is_true) then
                {
                   value = 1.0f
                }
            elif (condition_2_is_true) then
                {
                    value = 2.0f
                }
            else
                //HERE I don't know how to return nothing

        ]
    ]

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

ПРИМЕЧАНИЕ. Я знаю, что в конечном итоге есть лучшие способы инициализации списка, но я хотел бы понять, как заставить работать приведенный выше пример.

1 Ответ

1 голос
/ 04 декабря 2011

Вы, вероятно, хотите что-то вроде:

let level_1_docked_balls : List<List<option<float32>>> = 
    [ for i in 0 .. LineNumber - 1 -> 
        [ for j  in 0 .. BallsPerLine - 1 -> 
            if (condition_1_is_true) then Some 1.0f 
            elif (condition_2_is_true) then Some 2.0f 
            else None ]  ] 

Нельзя сказать, что по указанному индексу в списке нет ничего . Список - это просто список значений, и если вы не вернете значение, список будет короче. Если вы хотите представить float или ничего, тогда вы можете использовать тип F # option - значение Some 1.0f указывает, что существует значение 1.0f, а значение None указывает, что в этой позиции нет числа.

Я также изменил тип с float на float32 в аннотации типа. Тип float32 соответствует System.Single, а литералы записываются как 1.0f. Другой вариант - двойной (float с литералами 1.0).

В качестве примечания: если вы представляете некоторую 2D-матрицу и особенно если вам необходимо получить доступ к значению по указанному индексу, то, вероятно, лучше использовать 2D-массив. Хотя они изменчивы, вы можете использовать их неизменным образом, используя функции высшего порядка, такие как Array2D.map. Чтобы создать 2D-массив, похожий на ваш список, вы можете написать:

let level1 = Array2D.init LineNumber BallsPerLine (fun i j ->
  if (condition_1_is_true) then Some 1.0f 
  elif (condition_2_is_true) then Some 2.0f 
  else None)

РЕДАКТИРОВАТЬ Есть два варианта представления чего-то вроде шариков на карте игры. Либо используйте плотное представление, где у вас есть какое-то значение для каждого (i, j) - это то, что я описал ранее. Другой вариант - использовать представление sparse , в котором вы храните только список шаров вместе с индексом (i, j) , в котором находится шарик. Тогда вы могли бы написать что-то вроде:

let level_1_docked_balls : List<int * int * float32> = 
    [ for i in 0 .. LineNumber - 1 do
        for j  in 0 .. BallsPerLine - 1 do
          if (condition_1_is_true) then yield (i, j, 1.0f)
          elif (condition_2_is_true) then yield (i, j, 2.0f) ]

Когда вы используете do в цикле for, вы можете написать yield для генерации элемента, но вам не нужно возвращать значение в в каждом случае - там нет else ветки. Однако вам нужно знать индекс, которому принадлежит значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...