github.com/searKing/golang/go@v1.2.117/exp/slices/union.go (about)

     1  // Copyright 2022 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package slices
     6  
     7  // Union returns a slice satisfying c != zero within all c in the slice.
     8  // Union replaces consecutive runs of equal elements with a single copy.
     9  // This is like the uniq command found on Unix.
    10  // Union does not modify the contents of the slice s1 and s2; it creates a new slice.
    11  func Union[S ~[]E, E comparable](s1, s2 S) S {
    12  	if len(s1) == 0 {
    13  		return s2
    14  	}
    15  	if len(s2) == 0 {
    16  		return s1
    17  	}
    18  	m := make(map[E]struct{})
    19  	for _, v := range s1 {
    20  		m[v] = struct{}{}
    21  	}
    22  	for _, v := range s2 {
    23  		m[v] = struct{}{}
    24  	}
    25  
    26  	var ss S
    27  	for k := range m {
    28  		ss = append(ss, k)
    29  	}
    30  	return ss
    31  }
    32  
    33  // UnionFunc returns a slice satisfying f(c) within all c in the slice.
    34  // UnionFunc does not modify the contents of the slice s1 and s2; it creates a new slice.
    35  func UnionFunc[S ~[]E, E any](s1, s2 S, f func(v1, v2 E) bool) S {
    36  	if len(s1) == 0 {
    37  		return s2
    38  	}
    39  	if len(s2) == 0 {
    40  		return s1
    41  	}
    42  
    43  	var ss S
    44  	for _, v := range s1 {
    45  		if ContainsFunc(ss, func(e E) bool { return f(v, e) }) {
    46  			continue
    47  		}
    48  		ss = append(ss, v)
    49  	}
    50  	for _, v := range s2 {
    51  		if ContainsFunc(ss, func(e E) bool { return f(v, e) }) {
    52  			continue
    53  		}
    54  		ss = append(ss, v)
    55  	}
    56  	return ss
    57  }