首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Golang根据所有数组中的值创建数组

Golang根据所有数组中的值创建数组
EN

Stack Overflow用户
提问于 2019-07-12 13:19:45
回答 3查看 1.6K关注 0票数 1

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

代码语言:javascript
复制
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"]

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

我怎么能写一个能在戈朗实现这样一个目标的函数呢?

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

代码语言:javascript
复制
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
}

操场链接:https://play.golang.org/p/KRygw7OVBbn

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-07-12 14:36:56

根据我上面的评论,这里有一种方法可以使用go maps,从而避免迭代潜在的大片:

代码语言:javascript
复制
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

票数 3
EN

Stack Overflow用户

发布于 2019-07-12 14:36:47

想法:

  1. 跨数组(arr)计算每个项的表象数。
  2. 如果该数字与len(arr)完全相同,则项目将显示在所有数组中。

下面是一个员工采用这种方法的例子:

代码语言:javascript
复制
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"]
}

和操场链接:https://play.golang.org/p/FB3wJ7-gaIa

编辑:即使每个数组中有任何重复,它也会正常工作。

票数 0
EN

Stack Overflow用户

发布于 2019-11-07 05:14:35

@colminator是一个有效的答案,但算法不是最优的。@hallazang的建议是正确的,但如果我们只需要一张地图,为什么要创建2张地图呢?为提高效率,请参阅下一个选项。

代码语言:javascript
复制
func repeatingItemsFromArrays(arrays ...[]string) []string {
    la := len(arrays)
    out := []string{}

    // handle corner cases for efficiency
    if la == 0 {
        return out
    }
    if la == 1 {
        return arrays[0]
    }

    m := make(map[string]int)

    for i := range arrays {
        for j := range arrays[i] {
            m[arrays[i][j]]++
        }
    }

    for k, v := range m {
        if v == la {
            out = append(out, k)
        }
    }

    return out
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57007829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档