Dynamically Compare Objects?

Hey folks, I’m looking to dynamically inspect two objects, a and b, to find key/value pairs in b that either don’t exist in a or where the value differs. How can I do this?

  let aKeys = Js.Obj.keys(a)
  let bKeys = Js.Obj.keys(b)

  Js.Array2.forEach(aKeys, k => {
    switch Js.Array2.find(bKeys, bk => bk == k) {
      | Some(v) => if (a[k] == b[k]) { // ReScript doesn't like this
      | None => ...
    }
  })

Thanks!

Edit: I’ll add that Js.Dict.t likely won’t work here for me because I need a JS object that can hold values of different types.

1 Like

Dynamically looking up object fields isn’t possible in ReScript (and it wouldn’t be type-safe if it was). A function like this needs to be specific for the type it’s using.

if a["foo"] == b["foo"] { ...
if a["bar"] == b["bar"] { ...

But if the objects have different keys, then I think a bigger question is, why do you need to compare two objects which may be different types? If they’re not the same type (i.e. don’t have the same keys with the same types of values), then trying to use one instead of the other should get rejected by the typechecker anyway, and any comparison function wouldn’t make sense.

Depending on why you need to do this, then there are better ways to handle it. (For example, if it’s external JSON data, you can parse it into a ReScript variant first.)

1 Like