如何在golang中得到两个切片的交集? [英] How to get intersection of two slice in golang?

查看:130
本文介绍了如何在golang中得到两个切片的交集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Go中是否有任何有效的方法来获取两个切片的交集?

Is there any efficient way to get intersection of two slices in Go?

slice1 := []string{"foo", "bar","hello"}
slice2 := []string{"foo", "bar"}

intersection(slice1, slice2)
=> ["foo", "bar"]

字符串顺序无关紧要

推荐答案

是的,有几种解决方法.这是一个可以优化的示例.

Yes there are a few different ways to go about it.. Here's an example that can be optimized.

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", "bar", "hello", "bar"}
    slice2 := []string{"foo", "bar"}
    fmt.Printf("%+v\n", intersection(slice1, slice2))
}

现在,如上面的示例所示,上面定义的交集方法将仅对 strings slices 起作用.从理论上讲,您可以创建类似于的定义func交集(a []接口,b []接口)(inter []接口),但是您将依赖反射和类型转换,以便可以进行比较,这会增加延迟,并使代码难以处理读.对于您关心的每种类型,维护和阅读以编写单独的函数可能更容易.

Now the intersection method defined above will only operate on slices of strings, like your example.. You can in theory create a definition that looks like this func intersection(a []interface, b []interface) (inter []interface), however you would be relying on reflection and type casting so that you can compare, which will add latency and make your code harder to read. It's probably easier to maintain and read to write a separate function for each type you care about.

funcsectionString(a [] string,b [] string)(inter [] string)

funcintersectionInt(a [] int,b [] int)(inter [] int)

函数交叉点Float64(a [] Float64,b [] Float64)(inter [] Float64),..ect

然后,您可以创建自己的程序包,并在确定要实现的程序后重新使用它.

You can then create your own package and reuse once you settle how you want to implement it.

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)

这篇关于如何在golang中得到两个切片的交集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆