diff
diff copied to clipboard
Slice ordering can't be disabled for []map[string]interface{}
I am trying to compare slice of maps but the results are inconsistent. As I understand correctly the code below should show the same result for a == b and a == c
package main
import (
"fmt"
diff "github.com/r3labs/diff/v2"
)
func main() {
a := []map[string]interface{}{
{
"test": 2,
"a": "test",
},
{
"test": 12,
},
}
b := []map[string]interface{}{
{
"test": 2,
"a": "test1",
},
{
"test": 12,
},
}
c := []map[string]interface{}{
{
"test": 12,
},
{
"test": 2,
"a": "test1",
},
}
changelog1, _ := diff.Diff(a, b, diff.StructMapKeySupport(), diff.SliceOrdering(false))
changelog2, _ := diff.Diff(a, c, diff.StructMapKeySupport(), diff.SliceOrdering(false))
fmt.Println(changelog1)
fmt.Println(changelog2)
}
That would be awesome to ad an option that allows to have consistent results in this case
Hey @amanenk,
Sorry for the delay in getting back to you and thanks for raising the issue!
This is a bit of a tricky one...
When diffing two slices with SliceOrdering
set to false
, we:
- loop over each element in slice
a
and check if it has an exact match in sliceb
- loop over each element in slice
b
and check if it has an exact match in slicea
- add any element that does not have an exact equivalent in the other slice to a list
- diff the list of missing elements by order, as a fallback
Step 4
in this case is why changing the order of the slices in your example produces different results.
This works well for simple values like int
or string
where comparisons are binary; values match or they don't.
With more complicated values like map
s, it's possible to update one of many values in the map. At this point it's ambiguous as to which maps in each slice are equivalent.
It might be possible to try to find the best possible partial match in each slice, but I'm not confident that would actually produce more reliable results.