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

Slice ordering can't be disabled for []map[string]interface{} #71

Open
amanenk opened this issue Dec 8, 2021 · 1 comment
Open

Slice ordering can't be disabled for []map[string]interface{} #71

amanenk opened this issue Dec 8, 2021 · 1 comment

Comments

@amanenk
Copy link

amanenk commented Dec 8, 2021

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

@purehyperbole
Copy link
Member

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:

  1. loop over each element in slice a and check if it has an exact match in slice b
  2. loop over each element in slice b and check if it has an exact match in slice a
  3. add any element that does not have an exact equivalent in the other slice to a list
  4. 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 maps, 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.

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

2 participants