我试图找到一个解决方案来检查2片中的相等性.不幸的是,我发现的答案要求切片中的值处于相同的顺序.例如,http: //play.golang.org/p/yV0q1_u3xR将等式计算为false.
我想要一个可以[]string{"a","b","c"} == []string{"b","a","c"}评估的解决方案true.
更多示例
[]string{"a","a","c"} == []string{"c","a","c"} >>> false
[]string{"z","z","x"} == []string{"x","z","z"}>>>true
Joh*_*röm 17
您可以cmp.Diff与以下一起使用cmpopts.SortSlices:
less := func(a, b string) bool { return a < b }
equalIgnoreOrder := cmp.Diff(x, y, cmpopts.SortSlices(less)) == ""
Run Code Online (Sandbox Code Playgroud)
这是在Go Playground上运行的完整示例:
package main
import (
"fmt"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
func main() {
x := []string{"a", "b", "c"}
y := []string{"a", "c", "b"}
less := func(a, b string) bool { return a < b }
equalIgnoreOrder := cmp.Diff(x, y, cmpopts.SortSlices(less)) == ""
fmt.Println(equalIgnoreOrder) // prints "true"
}
Run Code Online (Sandbox Code Playgroud)
Raf*_*ypa 13
就像adrianlzt在他的回答中所写的那样,可以使用assert.ElementsMatchfrom testify的实现来实现这一点。但是,当您需要的只是比较的 bool 结果时,重用实际的 testify 模块而不是复制该代码怎么样?testify 中的实现旨在用于测试代码,并且通常带有testing.T参数。
事实证明,ElementsMatch 可以很容易地在测试代码之外使用。它所需要的只是一个带有ErrorF方法的接口的虚拟实现:
type dummyt struct{}
func (t dummyt) Errorf(string, ...interface{}) {}
func elementsMatch(listA, listB interface{}) bool {
return assert.ElementsMatch(dummyt{}, listA, listB)
}
Run Code Online (Sandbox Code Playgroud)
或者在The Go Playground上测试它,它是我根据 adrianlzt 的示例改编的。
这是一个替代解决方案,虽然可能有点冗长:
func sameStringSlice(x, y []string) bool {
if len(x) != len(y) {
return false
}
// create a map of string -> int
diff := make(map[string]int, len(x))
for _, _x := range x {
// 0 value for int is 0, so just increment a counter for the string
diff[_x]++
}
for _, _y := range y {
// If the string _y is not in diff bail out early
if _, ok := diff[_y]; !ok {
return false
}
diff[_y] -= 1
if diff[_y] == 0 {
delete(diff, _y)
}
}
if len(diff) == 0 {
return true
}
return false
}
Run Code Online (Sandbox Code Playgroud)
试试吧 Go Playground
概括testify ElementsMatch的代码,比较任何类型的对象的解决方案(在示例中[]map[string]string):
https://play.golang.org/p/xUS2ngrUWUl
其他答案有更好的时间复杂度O(N)VS (O(N log(N)),这是我的答案,也是我的解决方案将占用更多的内存,如果在片元素被频繁地重复,但我想补充它,因为我觉得这是应该做的最直接的方式它:
package main
import (
"fmt"
"sort"
"reflect"
)
func array_sorted_equal(a, b []string) bool {
if len(a) != len(b) {return false }
a_copy := make([]string, len(a))
b_copy := make([]string, len(b))
copy(a_copy, a)
copy(b_copy, b)
sort.Strings(a_copy)
sort.Strings(b_copy)
return reflect.DeepEqual(a_copy, b_copy)
}
func main() {
a := []string {"a", "a", "c"}
b := []string {"c", "a", "c"}
c := []string {"z","z","x"}
d := []string {"x","z","z"}
fmt.Println( array_sorted_equal(a, b))
fmt.Println( array_sorted_equal(c, d))
}
Run Code Online (Sandbox Code Playgroud)
结果:
false
true
Run Code Online (Sandbox Code Playgroud)
我认为最简单的方法是将每个数组/切片中的元素映射到它们的出现次数,然后比较这些映射:
func main() {
x := []string{"a","b","c"}
y := []string{"c","b","a"}
xMap := make(map[string]int)
yMap := make(map[string]int)
for _, xElem := range x {
xMap[xElem]++
}
for _, yElem := range y {
yMap[yElem]++
}
for xMapKey, xMapVal := range xMap {
if yMap[xMapKey] != xMapVal {
return false
}
}
return true
}
Run Code Online (Sandbox Code Playgroud)
您需要添加一些额外的注意事项,例如,如果阵列/切片包含不同类型或不同长度的元素,则会短路。
| 归档时间: |
|
| 查看次数: |
6856 次 |
| 最近记录: |