子集 JSON 数据

Subsetting JSON data

请考虑这个数据集:

type Deck = JsonProvider<"...">
let dt = Deck.GetSamples()

dt

[{"collectible":true,"health":4,"artist":"Zoltan Boros","type":"MINION","cost":1,"attack":2},
{"collectible":true,"health":8,"artist":"James Ryman","type":"MINION","cost":8,"attack":8},
{"collectible":true,"health":3,"artist":"Warren Mahy", "type":"LAND","cost":2,"attack":2}]

我正在尝试构建一个能够从中提取某些信息的函数,并最终将它们存储在一个较小的数据集中。给定一个类似列表的数据集 deck,它应该只考虑 key 等于给定 value 的卡片。

let rec filter deck key value =
    let rec aux l1 l2 l3 =
        match l1 with
        [] -> []
        | x::xs when x.l2 = l3 -> x::(aux xs key value)
    aux deck key value 

例如,

filter dt type minion

应该将牌组分成只有第一张和第二张牌的较小牌组。我想我在理解这个概念上向前迈出了几步,但它仍然不起作用,抛出一个错误

FS0072: Lookup on object of indeterminate type based on information prior to
this program point. A type annotation may be needed prior to this program point to 
constrain the type of the object. This may allow the lookup to be resolved.

如何定义key的类型?我尝试使用 key : stringkey : string list,但没有成功。

你实际上需要注释l1的类型。

设置l1: something list应该是你想要的。

Key 没有帮助,因为类型推断是从上到下的,而 x.l2auxkey 作为参数调用之前

您要重新实施 filter 吗?

#if INTERACTIVE
#r @"..\packages\FSharp.Data\lib\net40\FSharp.Data.dll"
#endif

open FSharp.Data

[<Literal>]
let jsonFile = @"C:\tmp\test.json"

type Json = JsonProvider<jsonFile>
let deck = Json.Load(jsonFile)

deck |> Seq.filter (fun c -> c.Type = "MINION") 

给我:

val it : seq.Root> = seq
[{ "collectible": true, "health": 4, "artist": "Zoltan Boros", "type": "MINION", "cost": 1, "attack": 2 };
{ "collectible": true, "health": 8, "artist": "James Ryman", "type": "MINION", "cost": 8, "attack": 8 }]