Worice Worice - 10 days ago 7
JSON Question

Subsetting JSON data

Please consider this dataset:

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}]


I am trying to build a function capable of extracting certain info from it and, eventually, store them in a smaller dataset. It should, given a list-like dataset
deck
, consider only the cards that for the
key
s equal to given
value
s.

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


For example,

filter dt type minion


should subset the deck in a smaller one with only the first and second card. I think I did few steps forward in getting the concept, but still it does not work, throwing an error of kind

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.


How should I define the type of
key
? I tried with
key : string
and
key : string list
, without succeed.

Answer

Are you trying to re-implement 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") 

Gives me:

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 }]