func (s *PathElementSet) Intersection(s2 *PathElementSet) *PathElementSet {
	out := &PathElementSet{}
	i, j := 0, 0
	for i < len(s.members) && j < len(s2.members) {
		if s.members[i].Less(s2.members[j]) {
			i++
		} else {
			if !s2.members[j].Less(s.members[i]) {
				out.members = append(out.members, s.members[i])
				i++
			}
			j++
		}
	}
	return out
}
Intersection returns a set containing elements which appear in both s and s2.
package fieldpath
import (
	"fmt"
	"sort"
	"strings"
	"sigs.k8s.io/structured-merge-diff/v4/value"
)
type PathElement struct {
	FieldName *string
	Key *value.FieldList
	Value *value.Value
	Index *int
}
func (e PathElement) Less(rhs PathElement) bool {
	return e.Compare(rhs) < 0
}
func (e PathElement) Compare(rhs PathElement) int {
	if e.FieldName != nil {
		if rhs.FieldName == nil {
			return -1
		}
		return strings.Compare(*e.FieldName, *rhs.FieldName)
	} else if rhs.FieldName != nil {
		return 1
	}
	if e.Key != nil {
		if rhs.Key == nil {
			return -1
		}
		return e.Key.Compare(*rhs.Key)
	} else if rhs.Key != nil {
		return 1
	}
	if e.Value != nil {
		if rhs.Value == nil {
			return -1
		}
		return value.Compare(*e.Value, *rhs.Value)
	} else if rhs.Value != nil {
		return 1
	}
	if e.Index != nil {
		if rhs.Index == nil {
			return -1
		}
		if *e.Index < *rhs.Index {
			return -1
		} else if *e.Index == *rhs.Index {
			return 0
		}
		return 1
	} else if rhs.Index != nil {
		return 1
	}
	return 0
}
func (e PathElement) Equals(rhs PathElement) bool {
	if e.FieldName != nil {
		if rhs.FieldName == nil {
			return false
		}
		return *e.FieldName == *rhs.FieldName
	} else if rhs.FieldName != nil {
		return false
	}
	if e.Key != nil {
		if rhs.Key == nil {
			return false
		}
		return e.Key.Equals(*rhs.Key)
	} else if rhs.Key != nil {
		return false
	}
	if e.Value != nil {
		if rhs.Value == nil {
			return false
		}
		return value.Equals(*e.Value, *rhs.Value)
	} else if rhs.Value != nil {
		return false
	}
	if e.Index != nil {
		if rhs.Index == nil {
			return false
		}
		return *e.Index == *rhs.Index
	} else if rhs.Index != nil {
		return false
	}
	return true
}
func (e PathElement) String() string {
	switch {
	case e.FieldName != nil:
		return "." + *e.FieldName
	case e.Key != nil:
		strs := make([]string, len(*e.Key))
		for i, k := range *e.Key {
			strs[i] = fmt.Sprintf("%v=%v", k.Name, value.ToString(k.Value))
		}
		return "[" + strings.Join(strs, ",") + "]"
	case e.Value != nil:
		return fmt.Sprintf("[=%v]", value.ToString(*e.Value))
	case e.Index != nil:
		return fmt.Sprintf("[%v]", *e.Index)
	default:
		return "{{invalid path element}}"
	}
}
func KeyByFields(nameValues ...interface{}) *value.FieldList {
	if len(nameValues)%2 != 0 {
		panic("must have a value for every name")
	}
	out := value.FieldList{}
	for i := 0; i < len(nameValues)-1; i += 2 {
		out = append(out, value.Field{Name: nameValues[i].(string), Value: value.NewValueInterface(nameValues[i+1])})
	}
	out.Sort()
	return &out
}
type PathElementSet struct {
	members sortedPathElements
}
func MakePathElementSet(size int) PathElementSet {
	return PathElementSet{
		members: make(sortedPathElements, 0, size),
	}
}
type sortedPathElements []PathElement
func (spe sortedPathElements) Len() int           { return len(spe) }
func (spe sortedPathElements) Less(i, j int) bool { return spe[i].Less(spe[j]) }
func (spe sortedPathElements) Swap(i, j int)      { spe[i], spe[j] = spe[j], spe[i] }
func (s *PathElementSet) Insert(pe PathElement) {
	loc := sort.Search(len(s.members), func(i int) bool {
		return !s.members[i].Less(pe)
	})
	if loc == len(s.members) {
		s.members = append(s.members, pe)
		return
	}
	if s.members[loc].Equals(pe) {
		return
	}
	s.members = append(s.members, PathElement{})
	copy(s.members[loc+1:], s.members[loc:])
	s.members[loc] = pe
}
func (s *PathElementSet) Union(s2 *PathElementSet) *PathElementSet {
	out := &PathElementSet{}
	i, j := 0, 0
	for i < len(s.members) && j < len(s2.members) {
		if s.members[i].Less(s2.members[j]) {
			out.members = append(out.members, s.members[i])
			i++
		} else {
			out.members = append(out.members, s2.members[j])
			if !s2.members[j].Less(s.members[i]) {
				i++
			}
			j++
		}
	}
	if i < len(s.members) {
		out.members = append(out.members, s.members[i:]...)
	}
	if j < len(s2.members) {
		out.members = append(out.members, s2.members[j:]...)
	}
	return out
}