我需要从多个数组创建一个数组。新数组必须仅包含传入的所有数组中存在的值。例如。
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"]
,因为它们是所有数组中唯一的值。
我该如何去编写可以在golang中实现这一目标的函数?
这是我的尝试,但感觉有点笨拙
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
}
答案 0 :(得分:2)
根据我上面的评论,这是使用go map
执行此操作的一种方法,因此避免了对可能较大的切片进行迭代:
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
}
答案 1 :(得分:0)
@colminator是一个有效的答案,但是算法不是最佳的。 @hallazang的建议是正确的方法,但是如果我们只需要一张地图,为什么还要创建两张地图呢?请参阅下一个选项以提高效率。
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
}
答案 2 :(得分:-1)
想法:
arr
)中的出现次数。len(arr)
完全相同,则该项目将出现在所有数组中。这是一个员工采用这种方法的示例:
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
编辑:即使每个数组中都有重复项,它也可以正常工作。