有没有有效的方法在Go中获得两个切片的交集?
我想避免嵌套for循环解决方案
slice1 := []string{"foo","bar","hello"} slice2 := []string{"foo","bar"} intersection(slice1,slice2) => ["foo","bar"]
字符串的顺序无关紧要
是的,有几种不同的方法可以解决它.这是一个可以优化的例子.
package main import "fmt" func intersection(a []string,b []string) (inter []string) { // interacting on the smallest list first can potentailly be faster...but not by much,worse case is the same low,high := a,b if len(a) > len(b) { low = b high = a } done := false for i,l := range low { for j,h := range high { // get future index values f1 := i + 1 f2 := j + 1 if l == h { inter = append(inter,h) if f1 < len(low) && f2 < len(high) { // if the future values aren't the same then that's the end of the intersection if low[f1] != high[f2] { done = true } } // we don't want to interate on the entire list everytime,so remove the parts we already looped on will make it faster each pass high = high[:j+copy(high[j:],high[j+1:])] break } } // nothing in the future so we are done if done { break } } return } func main() { slice1 := []string{"foo","hello","bar"} slice2 := []string{"foo","bar"} fmt.Printf("%+v\n",intersection(slice1,slice2)) }
现在上面定义的交集方法只会对字符串切片进行操作,就像你的例子一样.理论上你可以创建一个看起来像这个func交集的定义(a []接口,b []接口)(inter []接口),但是你会依赖于反射和类型转换,这样你就可以比较,这将增加延迟并使你的代码更难阅读.维护和阅读可能更容易为您关心的每种类型编写单独的函数.
func intersectionString(a [] string,b [] string)(inter [] string),
func intersectionInt(a [] int,b [] int)(inter [] int),
func intersectionFloat64(a [] Float64,b [] Float64)(inter [] Float64),..
然后,您可以创建自己的包,并在确定要实现它的方式后重复使用.
package intersection func String(a []string,b []string) (inter []string) func Int(a []int,b []int) (inter []int) func Float64(a []Float64,b []Float64) (inter []Float64)