我需要从多个数组创建一个数组。新数组只能包含传入的所有数组中存在的值。例如。
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"],因为它们是所有数组中唯一的值。
我怎么能写一个能在戈朗实现这样一个目标的函数呢?
这是我的尝试,但感觉有点笨拙。
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
}发布于 2019-07-12 14:36:56
根据我上面的评论,这里有一种方法可以使用go maps,从而避免迭代潜在的大片:
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
}发布于 2019-07-12 14:36:47
想法:
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
编辑:即使每个数组中有任何重复,它也会正常工作。
发布于 2019-11-07 05:14:35
@colminator是一个有效的答案,但算法不是最优的。@hallazang的建议是正确的,但如果我们只需要一张地图,为什么要创建2张地图呢?为提高效率,请参阅下一个选项。
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
}https://stackoverflow.com/questions/57007829
复制相似问题