使用Golang做一些Array数据操作时,不像Dart内置了Set的交集Intersection、并集Union、差集Difference等操作,非常不方便,只能自己实现一个。

鉴于泛型是go1.18后才有得,以下代码需要使用go1.18及以上版本才能正常执行

代码

 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
45
46
47
48
49
50
51
52
// 创建一个 interface 包含泛型需要的限定类型,也可以不做任何限制。
type Num interface {
	~int | ~uint | ~uint8 | ~int8 | ~int32 | ~uint32 | ~int64 | ~uint64
}

// 交集
func Intersection[T Num](a, b []T) (c []T) {
	m := make(map[T]bool)

	for _, item := range a {
		m[item] = true
	}

	for _, item := range b {
		if _, ok := m[item]; ok {
			c = append(c, item)
		}
	}
	return
}

// 并集
func Union[T Num](a, b []T) []T {
	m := make(map[T]bool)

	for _, item := range a {
		m[item] = true
	}

	for _, item := range b {
		if _, ok := m[item]; !ok {
			a = append(a, item)
		}
	}
	return a
}

// 差集 Set Difference: A - B
func Difference[T Num](a, b []T) (diff []T) {
	m := make(map[T]bool)

	for _, item := range b {
		m[item] = true
	}

	for _, item := range a {
		if _, ok := m[item]; !ok {
			diff = append(diff, item)
		}
	}
	return
}

测试代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
func main() {

	a := []int8{1, 2, 3, 4}
	b := []int8{4, 5, 6}
	c := common.Union(a, b)

	fmt.Printf("a:%#v b:%#v 并集:%#v\n", a, b, c)
	c = common.Intersection(a, b)
	fmt.Printf("a:%#v b:%#v 交集:%#v\n", a, b, c)
	c = common.Difference(a, b)
	fmt.Printf("a:%#v b:%#v 差集 a - b:%#v\n", a, b, c)
	c = common.Difference(b, a)
	fmt.Printf("a:%#v b:%#v 差集 b - a:%#v\n", a, b, c)

}

执行结果

1
2
3
4
a:[]int8{1, 2, 3, 4} b:[]int8{4, 5, 6} 并集:[]int8{1, 2, 3, 4, 5, 6}
a:[]int8{1, 2, 3, 4} b:[]int8{4, 5, 6} 交集:[]int8{4}
a:[]int8{1, 2, 3, 4} b:[]int8{4, 5, 6} 差集 a - b:[]int8{1, 2, 3}
a:[]int8{1, 2, 3, 4} b:[]int8{4, 5, 6} 差集 b - a:[]int8{5, 6}

性能优化

数据量过大时可能需要进行性能优化