-
Notifications
You must be signed in to change notification settings - Fork 0
/
slice.go
44 lines (40 loc) · 1.25 KB
/
slice.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package dtomerge
import (
"fmt"
"reflect"
)
func mergeComparableSlicesUnique(src, patch reflect.Value) (reflect.Value, error) {
result := reflect.MakeSlice(src.Type(), 0, src.Len())
srcElemsMap := reflect.MakeMap(reflect.MapOf(src.Type().Elem(), reflect.TypeOf(true)))
// index all src elements
trueValue := reflect.ValueOf(true)
for i := 0; i < src.Len(); i++ {
elem := src.Index(i)
srcElemsMap.SetMapIndex(elem, trueValue)
result = reflect.Append(result, elem)
}
for i := 0; i < patch.Len(); i++ {
if foundSrcElam := srcElemsMap.MapIndex(patch.Index(i)); !foundSrcElam.IsValid() {
result = reflect.Append(result, patch.Index(i))
}
}
return result, nil
}
func mergeSlicesByIndex(src, patch reflect.Value, mCtx mergeContext) (reflect.Value, error) {
result := reflect.MakeSlice(src.Type(), 0, src.Len())
for i := 0; i < src.Len(); i++ {
result = reflect.Append(result, src.Index(i))
}
for i := 0; i < patch.Len(); i++ {
if i < result.Len() {
mergedElement, err := mergeAny(result.Index(i), patch.Index(i), mCtx)
if err != nil {
return reflect.Value{}, fmt.Errorf("merging patch slice[%d]: %w", i, err)
}
result.Index(i).Set(mergedElement)
} else {
result = reflect.Append(result, patch.Index(i))
}
}
return result, nil
}