将计算出的键添加到集合中
Add calculated key to collection
请考虑这个由男人和女人组成的数据集,我根据几个变量在第二时刻过滤:
type ls = JsonProvider<"...">
let dt = ls.GetSamples()
let dt2 =
dt |> Seq.filter (fun c -> c.Sex = "male" && c.Height > Some 150)
dt2
[{"sex":"male","height":180,"weight":85},
{"sex":"male","height":160" "weight":60},
{"sex":"male","height":180,"weight":85}]
假设我想添加第四个键 "body mass index" 或 "bmi",其值大致由 "weight"/"height" 给出。因此我预计:
[{"sex":"male","height":180,"weight":85, "bmi":(180/85)},
{"sex":"male","height":160" "weight":60, "bmi":(160/60},
{"sex":"male","height":180,"weight":85, "bmi":(180/85)}]
我认为 map.Add 可能会有帮助。
let dt3 = dt2.Add("bmi", (dt2.Height/dt2.Weight))
不幸的是,它 returns 一个错误:
error FS0039: The field, constructor or member 'Add' is not defined
我确定我的代码中还有更多错误,但如果没有这个函数,我实际上无法查找它们。至少我是否正确地解决了这个问题?
创建 JSON 的修改版本令人遗憾的是,F# 数据类型提供程序并没有使它变得特别容易。困难在于我们可以从源 JSON 推断类型,但我们无法 "predict" 人们可能想要添加什么样的字段。
为此,您需要访问 JSON 值的底层表示并对其进行操作。例如:
type ls = JsonProvider<"""
[{"sex":"male","height":180,"weight":85},
{"sex":"male","height":160,"weight":60},
{"sex":"male","height":180,"weight":85}]""">
let dt = ls.GetSamples()
let newJson =
dt
|> Array.map (fun recd ->
// To do the calculation, you can access the fields via inferred types
let bmi = float recd.Height / float recd.Weight
// But now we need to look at the underlying value, check that it is
// a record and extract the properties, which is an array of key-value pairs
match recd.JsonValue with
| JsonValue.Record props ->
// Append the new property to the existing properties & re-create record
Array.append [| "bmi", JsonValue.Float bmi |] props
|> JsonValue.Record
| _ -> failwith "Unexpected format" )
// Re-create a new JSON array and format it as JSON
JsonValue.Array(newJson).ToString()
请考虑这个由男人和女人组成的数据集,我根据几个变量在第二时刻过滤:
type ls = JsonProvider<"...">
let dt = ls.GetSamples()
let dt2 =
dt |> Seq.filter (fun c -> c.Sex = "male" && c.Height > Some 150)
dt2
[{"sex":"male","height":180,"weight":85},
{"sex":"male","height":160" "weight":60},
{"sex":"male","height":180,"weight":85}]
假设我想添加第四个键 "body mass index" 或 "bmi",其值大致由 "weight"/"height" 给出。因此我预计:
[{"sex":"male","height":180,"weight":85, "bmi":(180/85)},
{"sex":"male","height":160" "weight":60, "bmi":(160/60},
{"sex":"male","height":180,"weight":85, "bmi":(180/85)}]
我认为 map.Add 可能会有帮助。
let dt3 = dt2.Add("bmi", (dt2.Height/dt2.Weight))
不幸的是,它 returns 一个错误:
error FS0039: The field, constructor or member 'Add' is not defined
我确定我的代码中还有更多错误,但如果没有这个函数,我实际上无法查找它们。至少我是否正确地解决了这个问题?
创建 JSON 的修改版本令人遗憾的是,F# 数据类型提供程序并没有使它变得特别容易。困难在于我们可以从源 JSON 推断类型,但我们无法 "predict" 人们可能想要添加什么样的字段。
为此,您需要访问 JSON 值的底层表示并对其进行操作。例如:
type ls = JsonProvider<"""
[{"sex":"male","height":180,"weight":85},
{"sex":"male","height":160,"weight":60},
{"sex":"male","height":180,"weight":85}]""">
let dt = ls.GetSamples()
let newJson =
dt
|> Array.map (fun recd ->
// To do the calculation, you can access the fields via inferred types
let bmi = float recd.Height / float recd.Weight
// But now we need to look at the underlying value, check that it is
// a record and extract the properties, which is an array of key-value pairs
match recd.JsonValue with
| JsonValue.Record props ->
// Append the new property to the existing properties & re-create record
Array.append [| "bmi", JsonValue.Float bmi |] props
|> JsonValue.Record
| _ -> failwith "Unexpected format" )
// Re-create a new JSON array and format it as JSON
JsonValue.Array(newJson).ToString()