Skip to content
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

How to ignore specific field by name? #336

Closed
criscola opened this issue Aug 24, 2023 · 1 comment
Closed

How to ignore specific field by name? #336

criscola opened this issue Aug 24, 2023 · 1 comment

Comments

@criscola
Copy link

criscola commented Aug 24, 2023

Hello, I hope you can help me. I would like to know if it's possible to ignore a specific field during comparison. I had a look at this #156 and tried to modify it a bit to make it work for my use case, but I don't understand how to do it.
For more context: my objective is to compare two JSON strings, ignoring a specific field by name present in various levels of the hierarchy. Thank you!

Test samples:

{
"name": "foo",
"archived": false,
"birth_date": "2016-05-01T00:00:00Z",
"edges": {
  "firstEdge": {
    "id": 1438,
    "edges": {
      "arrayOfStuff": [
        {
          "id": 98,
          "create_time": "2023-08-22T22:32:31.681874237+02:00",
          "update_time": "2023-08-22T22:32:31.681874317+02:00",
          "edges": {
            "yetAnotherEdge": {
              "id": 98,
              "some_date": "2020-11-02T00:00:00Z",
              "create_time": "2023-08-22T22:32:31.680396095+02:00",
              "update_time": "2023-08-22T22:32:31.680396165+02:00"
            }
          }
        }]
      }
    }
  }
}

compared to this (only create and update times are changed):

{
"name": "foo",
"archived": false,
"birth_date": "2016-05-01T00:00:00Z",
"edges": {
  "firstEdge": {
    "id": 1438,
    "edges": {
      "arrayOfStuff": [
        {
          "id": 98,
          "create_time": "1999-08-22T22:32:31.681874237+02:00",
          "update_time": "1999-08-22T22:32:31.681874317+02:00",
          "edges": {
            "yetAnotherEdge": {
              "id": 98,
              "some_date": "1999-11-02T00:00:00Z",
              "create_time": "1999-08-22T22:32:31.680396095+02:00",
              "update_time": "1999-08-22T22:32:31.680396165+02:00"
            }
          }
        }]
      }
    }
  }
}

should return a match. I know that I can use some trick like reflection to zero-out the fields, or unmarshal into a struct omitting the values, but if I can implement what I found with go-cmp it would definitely lead to more clear, concise and maintenable code.

@criscola
Copy link
Author

Turns out, it is pretty simple! Here FilterPath is necessary because FilterValues is used to ignore based on values, for example to compare float values etc. but in my case I needed to ignore a path which includes the left-hand side of the "map entry" in the predicate. Simple get all the leaves with p.Last() and you're set:

opt := cmp.FilterPath(func(p cmp.Path) bool {
    vx := p.Last().String()
    
    if vx == `["create_time"]` || vx == `["update_time"]` {
	    return true
    }
    return false
}, cmp.Ignore())

note also that if you know your struct in advance, you can use IgnoreFields as in the docs (in my case, I don't know, hence I had to use the jsonTransformer as in #156).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant