fsprojects / FSharp.Data

F# Data: Library for Data Access
https://fsprojects.github.io/FSharp.Data
Other
814 stars 288 forks source link

Added InferDictionariesFromRecords flag to JSON TP #1430

Closed nikoyak closed 2 years ago

nikoyak commented 2 years ago

JSON TP always projects json record fields into the properties of generated types. Sometimes it is not desirable. The added flag will allow to infer dictionaries from the records if the names of all the fields of similar records in the provider's training data are inferred to the same non-string primitive type (by type inference rules). The flag is not set by default for backwards compatibility.

The current implementation makes it meaningless to process such data in the JSON Provider:

{ "sales": { "2022-01-13": { "count": 3 }, "2022-01-23": { "count": 5 }, "2022-01-28": { "count": 4 }, "2022-02-01": { "count": 5 }, "2022-02-07": { "count": 1 }, "2022-02-13": { "count": 2 } } }

With this PR, for example, it is easy to find out from the above data how many sales were in February:

type TP = JsonProvider<"""{ "sales": { "1970-01-01": { "count": 100 }}}""", InferDictionariesFromRecords = true>
let s = """{ "sales": { "2022-01-13": { "count": 3 }, "2022-01-23": { "count": 5 }, "2022-01-28": { "count": 4 }, "2022-02-01": { "count": 5 }, "2022-02-07": { "count": 1 }, "2022-02-13": { "count": 2 } } }"""
TP.Parse(s).Sales.Items
|> Seq.filter (fun (k, _) -> k.Month = 2)
|> Seq.sumBy (fun (_, v) -> v.Count)

In addition to the Items: (InferedKey * InferedValue) seq property specified in the code above, the generated dictionary-like type contains the Count, IsEmpty, Keys, Values properties, the Item indexed property, and the ContainsKey, TryFind methods, similar to the members of FSharp.Collections.Map

dsyme commented 2 years ago

Suggest PreferDictionaries instead of InferDictionariesFromRecords

dsyme commented 2 years ago

I left a couple of suggestions, but otherwise marked as approved, the code looks great

nikoyak commented 2 years ago

done

cartermp commented 2 years ago

Thanks!