From b1b7eca0eb9b2fe3024de5b0561f8133458d5fba Mon Sep 17 00:00:00 2001 From: Aleksandr Rybolovlev Date: Thu, 4 Jan 2024 09:40:00 +0100 Subject: [PATCH] Update slice.DeepEqual and its unit test --- internal/slice/slice.go | 27 +++++++------ internal/slice/slice_test.go | 77 ++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 36 deletions(-) diff --git a/internal/slice/slice.go b/internal/slice/slice.go index d0007838..c8efe4f4 100644 --- a/internal/slice/slice.go +++ b/internal/slice/slice.go @@ -26,25 +26,30 @@ func DeepEqual[A any](a, b []A) bool { } if a == nil || b == nil { - return true + return cmp.Equal(a, b) } if reflect.TypeOf(a) != reflect.TypeOf(b) { return false } - for _, va := range a { - found := false - for _, vb := range b { - if cmp.Equal(va, vb) { - found = true - break - } - } - if !found { + ma := make(map[any]int) + mb := make(map[any]int) + + for i := 0; i < len(a); i++ { + ma[a[i]]++ + mb[b[i]]++ + } + + for va := range ma { + if _, ok := mb[va]; !ok { return false } + mb[va]-- + if mb[va] == 0 { + delete(mb, va) + } } - return true + return len(mb) == 0 } diff --git a/internal/slice/slice_test.go b/internal/slice/slice_test.go index bf72d8fd..4d3521f9 100644 --- a/internal/slice/slice_test.go +++ b/internal/slice/slice_test.go @@ -26,44 +26,71 @@ func TestRemoveFromSlice(t *testing.T) { } func TestDeepEqual(t *testing.T) { - input := []map[string][]any{ + cases := []struct { + A []any + B []any + Expected bool + }{ { - "A": {}, - "B": {}, + A: []any{}, + B: []any{}, + Expected: true, }, { - "A": nil, - "B": nil, + A: nil, + B: nil, + Expected: true, }, { - "A": {}, - "B": nil, + A: []any{1, 2, 3}, + B: []any{1, 2, 3}, + Expected: true, }, { - "A": {1, 2, 3}, - "B": {1, 2, 3}, + A: []any{1, 2, 3}, + B: []any{3, 1, 2}, + Expected: true, }, { - "A": {"a", "b", "c"}, - "B": {"b", "c"}, + A: []any{}, + B: nil, + Expected: false, }, { - "A": {1, 2}, - "B": {"b", "c"}, + A: nil, + B: []any{1, 2, 3}, + Expected: false, + }, + { + A: []any{1, 1, 1, 2, 3}, + B: []any{1, 1, 2, 2, 3}, + Expected: false, + }, + { + A: []any{"a", "b", "c"}, + B: []any{"b", "c"}, + Expected: false, + }, + { + A: []any{1, 2}, + B: []any{"b", "c"}, + Expected: false, + }, + { + A: []any{1, 1}, + B: []any{1, 5}, + Expected: false, + }, + { + A: []any{1, 5}, + B: []any{1, 1}, + Expected: false, }, } - want := []bool{ - true, - true, - true, - true, - false, - false, - } - for i, s := range input { - r := DeepEqual(s["A"], s["B"]) - if r != want[i] { - t.Errorf("The wanted result [%t] does not match with the produced [%v] at [%d]", want[i], r, i) + for i, s := range cases { + r := DeepEqual(s.A, s.B) + if r != s.Expected { + t.Errorf("The wanted result [%t] does not match with the produced [%v] at [%d]", s.Expected, r, i) } } }