-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Way to update Yojson.Basic.json member? #54
Comments
No, there isn't such thing. We could add it, but we'd also need to add similar functions for mutating data, with consistent naming. Hopefully we won't end up embedding a full javascript implementation. |
I'm brand new to OCaml but would be willing to have a try at this. Do you know any examples of these update functions @mjambon? I've found one StackOverflow post so far. Oooh! 🎉 There's also Map.update. |
I've been hacking away on this tonight to transfer over the Map.update syntax to update a JSON object as an `Assoc (string : json) list. Any thoughts? Is this anywhere near what you're expecting? The functions to add or remove could be based on this? 🤔 -- Edit: The provided code did not add the member if it wasn't in the JSON object. 👎I've removed the incorrect suggested code. |
I've made some progress! 🎉 Here's a function that's uses the same syntax as val add : (key: string) -> (v': json) -> (json: json) -> (json': json)
val remove : (key: string) -> (json: json) -> (json': json) Here's what I'd propose for
let update key f (json : Yojson.Basic.json) =
let rec update_json_obj = function
| [] ->
begin match f None with
| None -> []
| Some v -> [(key, v)]
end
| ((k, v) as m) :: tl ->
if k = key then
match f (Some v) with
| None -> update_json_obj tl
| Some v' ->
if v' == v then m :: tl
else (k, v') :: tl
else m :: (update_json_obj tl)
in
match json with
| `Assoc obj -> `Assoc (update_json_obj obj)
| _ -> json
;; with the following test cases (evalated in (* No change - New value, add None *)
Yojson.Basic.from_string "{}" |> update "a" (fun _ -> None);;
(* Add value - Empty list *)
Yojson.Basic.from_string "{}" |> update "a" (fun _ -> Some (`Int 1));;
(* Add value - Append to end of list*)
Yojson.Basic.from_string "{a:1}" |> update "b" (fun _ -> Some (`Int 2));;
(* Update value - Change *)
Yojson.Basic.from_string "{a:1}" |> update "a" (fun _ -> Some (`String "one"));;
(* Update value - No change when physical equality *)
let values = `Assoc [("a", `Int 1); ("b", `Int 2)] in
let json = `Assoc [("values", values)] in
let json' = json |> update "values" (fun _ -> Some (values)) in
(Yojson.Basic.Util.member "values") json == (Yojson.Basic.Util.member "values" json');;
(* Remove *)
Yojson.Basic.from_string "{a:1}" |> update "a" (fun _ -> None);; and the trivial implementation for let add k v = update k (fun _ -> Some v)
let remove k = update k (fun _ -> None) |
As I mentioned before, I don't like the API but it's "familiar". Would you want a PR with these changes? Any pointers on how things are tested in the repo (or OCaml)? |
I've taken a copy of this code and hacked on it a bit to use it locally,
definitely appreciate this functionality! Thank you!
…On Fri, Feb 15, 2019 at 7:12 AM Sean Poulter ***@***.***> wrote:
As I mentioned before, I don't like the API but it's "familiar". Would you
want a PR with these changes? Any pointers on how things are tested in the
repo (or OCaml)?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#54 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AACJ4INCpiKQ1KxNad7XlfKnJWBfFadfks5vNs5agaJpZM4SmIS8>
.
|
It seems like there's a demand for such functions so I suggest you open a PR with what you have so far and we can discuss the details there. Is that fine by you? |
If I have a json object, is there a function that takes a member, a function of
Yojson.Basic.member -> Yojson.Basic.member
, and returns a new json object with an updated value at the key?I'm looking for something similar to OCaml's
with
, specifically because I need to update a list of a key to shorten it to a sublist, then pass the whole structure to another function.The text was updated successfully, but these errors were encountered: