#list #f#
#Список #f#
Вопрос:
У меня есть такой список
let data = [{ A = "one"; B = 2020; C = Some 5L; D = None };
{ A = "two"; B = 2020; C = None; D = Some 3L}]
как мне заменить C = Some 5L;
на C = 5;
я хочу вот так ->
[{ A = "one"; B = 2020; C = 5; D = null };
{ A = "two"; B = 2020; C = null; D = 3}]
я пытался let newData = data |> List.choose id
Это не работает.
Комментарии:
1. То, что вы хотите, не имеет никакого смысла. Почему вы хотите, чтобы это было так?
2. эти записи поступают из базы данных C или D может быть нулевым или некоторым значением int
3. Тогда в вашем желаемом результате вы должны иметь
C = null
вместоC = None
и вы можете сопоставить его, как предлагает ajuch, с int? просто установите для него значение null, когда оно равно none.4. Проблема в том, что у вас не может быть 2 разных типа в списке.
None
имеет типOption<int>
, тогда5
как это типint
. Они не могут быть в одном списке. Записи имеют разные типы.5. Вместо nullable в F # вы используете
Option
тип. Это правильный способ обработки возможных пропущенных значений. В противном случае ваш код небезопасен.
Ответ №1:
Вы можете использовать System.Nullable для представления типов с нулевым значением, которые C # должен распознавать. Также вам нужно будет создать отдельный тип записи для представления ваших данных с полями с возможностью обнуления. Я могу себе представить, что вам нужно совершить такую транзакцию при выходе из мира F # и входе в C #.
type A = { A:string; B: int; C: int64 option; D: int64 option}
type T = { A2:string; B2: int; C2: System.Nullable<int64>; D2: System.Nullable<int64>}
let data = [{ A = "one"; B = 2020; C = Some 5L; D = None };
{ A = "two"; B = 2020; C = None; D = Some 3L}]
let getNullable (x: int64 option) =
match x with
| Some v -> System.Nullable(v)
| None -> System.Nullable()
let nullablData (data : A list)=
data |> List.map (fun x -> {A2 = x.A; B2 = x.B; C2 = getNullable(x.C); D2 = getNullable(x.D)})
let res= nullablData data
//result
//val res : T list = [{A2 = "one"; B2 = 2020; C2 = 5L; D2 = null;};
// {A2 = "two"; B2 = 2020; C2 = null; D2 = 3L;}]
Ответ №2:
На самом деле вы хотите отобразить элементы списка в другой тип. Поскольку запись, которую вы используете внутри списка, выглядит так
type X = {
A: string
B: int
C: int option
D: obj option
}
и вы хотите иметь
type Y = {
A: string
B: int
C: int
D: obj option
}
(обратите внимание на тип для C), вам нужно преобразовать элементы списка с List.map
помощью функции, которая отображает тип X в тип Y.
data |> List.map (fun x -> { A = x.A; B = x.B; C = (x.C |> Option.defaultValue 0); D = x.D})
Вы должны правильно обработать C=None
случай, присвоив ему значение по умолчанию.
Комментарии:
1. Я обновил вопрос. У меня не может быть 0, когда оно равно none.
2. В этом случае вы можете использовать
List.choose
вместоList.map
, чтобы исключить элементы, которые имеютNone
. Функция будет такой:(fun x -> if x.C.IsNone then None else Some { A = .x.A ...
где остальное то же самое.