duanlu9816
2019-07-12 13:19
浏览 200
已采纳

Golang从所有数组中存在的值创建数组

I need to create an array from multiple arrays. The new array must only contain the values that is present in all arrays passed in. For example.

array1 := []string{"hello", "germany", "brasil", "fiji"}
array2 := []string{"goodbye", "germany", "brasil", "fiji"}
array3 := []string{"hello", "brasil", "fiji"}
array4 := []string{"hello", "brasil", "fiji", "usa"}

func mergeArrays(arrs ...[]string) []string{
   // process arrays
}

myNewArray := mergeArrays(array1,array2,array3,array4)
fmt.Println(myNewArray) // ["fiji", "brasil"]

The example should return ["fiji", "brasil"] since they are the only values present in all arrays.

How could I go about writing a function that could achieve such a goal in golang?

This is my attempt but feels a bit clumsy

func mergeArrays(arrs ...[]string) []string {
    var finalArr []string
    if len(arrs) == 0 {
        return finalArr
    }

    for i, a := range arrs {
        if i == 0 {
            finalArr = arrs[0]
            continue
        }
        for i, e := range finalArr {
            if !strContains(a, e) {
                finalArr = append(finalArr[:i], finalArr[i+1:]...)
            }
        }

    }

    return finalArr
}

func strContains(s []string, e string) bool {
    for _, a := range s {
        if a == e {
            return true
        }
    }
    return false
}

Playground link: https://play.golang.org/p/KRygw7OVBbn

图片转代码服务由CSDN问答提供 功能建议

我需要从多个数组创建一个数组。 新数组只能包含传入的所有数组中存在的值。例如。

  array1:= [] string {“ hello”,“ germany”,“  brasil”,“ fiji”} 
array2:= [] string {“ goodbye”,“德国”,“ brasil”,“ fiji”} 
array3:= [] string {“ hello”,“ brasil”,“ fiji”  } 
array4:= [] string {“ hello”,“ brasil”,“ fiji”,“ usa”} 
 
func mergeArrays(arrs ... [] string)[] string {
 //处理数组\  n} 
 
myNewArray:= mergeArrays(array1,array2,array3,array4)
fmt.Println(myNewArray)// [“斐济”,“巴西”] 
   
 
  

该示例应返回 [“ fiji”,“ brasil”] ,因为它们是所有数组中唯一的值。

我该怎么办

这是我的尝试,但感觉有点笨拙

  func mergeArrays(arrs  ... [] string)[] string {
 var finalArr [] string 
如果len(arrs)== 0 {
返回finalArr 
} 
 
对于i,:= range arrs {\ 如果i == 0 {
  finalArr = arrs [0] 
继续
} 
对于i,e:=范围finalArr {
如果!strContains(a,e){
 finalArr = append(finalArr [:i],finalArr [i +  1:] ...)
} 
} 
 
} 
 
返回finalArr 
} 
 
func strContains(s [] string,e string)bool {
表示_,a:  = range s {
,如果a == e {
返回true 
} 
} 
返回false 
} 
   
 
 

游乐场链接:< a href =“ https://play.golang.org/p/KRygw7OVBbn” rel =“ nofollow noreferrer”> https://play.golang.org/p/KRygw7OVBbn

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • duan1443 2019-07-12 14:36
    已采纳

    Per my comment above, here's one way to do it with go maps and thus avoid iterating over potentially large slices:

    func itemize(a []string) map[string]struct{} {
        m := make(map[string]struct{})
        for _, v:=range a {
            m[v] = struct{}{} // struct{}{} == an empty struct (i.e. a value that incurs no storage)
        }
        return m
    }
    
    func commonElements(arrs ...[]string) (results []string) {
        if len(arrs) == 0 {
            return // edge case
        }
    
        mm := itemize(arrs[0]) // master map
    
        for i:=1; i<len(arrs);i++ {
            m := itemize(arrs[i]) // current map
            for k := range mm {
                if _, ok := m[k]; !ok {
                    delete(mm, k) // master item not in current slice, so remove from master
                }
            }
        }
    
        results = make([]string, len(mm)) // make a precisely sized slice...
        i:=0
        for k := range mm {
            results[i] = k // so we can insert results directly into it without using append
            i++ 
        }
    
        return
    }
    

    https://play.golang.org/p/pTaXR-nY9zm

    点赞 评论
  • douyun3799 2019-07-12 14:36

    Idea:

    1. Count number of appearances of each item across arrays(arr).
    2. If that number is exactly same as len(arr), the item presents in all arrays.

    Here's an example that employees this approach:

    package main
    
    import "fmt"
    
    func uniq(arr []string) []string {
        cache := make(map[string]struct{})
        for _, s := range arr {
            cache[s] = struct{}{}
        }
        var r []string
        for s := range cache {
            r = append(r, s)
        }
        return r
    }
    
    func mergeArrays(arrs ...[]string) []string {
        count := make(map[string]int)
        for _, arr := range arrs {
            for _, s := range uniq(arr) {
                count[s]++
            }
        }
        var merged []string
        for s, n := range count {
            if n == len(arrs) {
                merged = append(merged, s)
            }
        }
        return merged
    }
    
    func main() {
        array1 := []string{"hello", "germany", "brasil", "fiji"}
        array2 := []string{"goodbye", "germany", "brasil", "fiji"}
        array3 := []string{"hello", "brasil", "fiji"}
        array4 := []string{"hello", "brasil", "fiji", "usa"}
    
        myNewArray := mergeArrays(array1, array2, array3, array4)
        fmt.Println(myNewArray) // ["fiji", "brasil"]
    }
    

    And playground link: https://play.golang.org/p/FB3wJ7-gaIa

    EDIT: it will work properly even if there's any duplicate in each array.

    点赞 评论

相关推荐 更多相似问题