Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 在Go切片或数组中查找唯一项_Arrays_Go_Set_Unique_Slice - Fatal编程技术网

Arrays 在Go切片或数组中查找唯一项

Arrays 在Go切片或数组中查找唯一项,arrays,go,set,unique,slice,Arrays,Go,Set,Unique,Slice,我是个新手,现在真的很困惑 假设我有一个坐标列表,在这个坐标列表中有一些双精度的。我一辈子都想不出如何列出一份独特的清单。通常在Python中,我可以使用集合和其他内置项“作弊”。没有那么多人去 package main import ( "fmt" "reflect" ) type visit struct { x, y int } func main() { var visited []visit var unique []visit

我是个新手,现在真的很困惑

假设我有一个坐标列表,在这个坐标列表中有一些双精度的。我一辈子都想不出如何列出一份独特的清单。通常在Python中,我可以使用集合和其他内置项“作弊”。没有那么多人去

package main

import (
    "fmt"
    "reflect"
)

type visit struct {
    x, y int
}

func main() {
    var visited []visit
    var unique []visit

    visited = append(visited, visit{1, 100})
    visited = append(visited, visit{2, 2})
    visited = append(visited, visit{1, 100})
    visited = append(visited, visit{1, 1})

    unique = append(unique, visit{1, 1})

    fmt.Println(unique)

    // Go through the visits and find the unique elements
    for _, v := range visited {
        for _, u := range unique {

            fmt.Printf("Here's unique: %v\n", unique)
            fmt.Printf("Comparing %v to %v is %v\n", v, u, reflect.DeepEqual(v, u))

            if reflect.DeepEqual(v, u) {
                fmt.Println("Skip")
            } else {
                unique = append(unique, v)
            }
        }
    }

    fmt.Println(unique)
}

您的代码中有多个错误。最严重的是,由于您将访问的
片段的每个特定元素与
唯一的
元素的所有进行比较,因此如果
唯一的
至少包含一个不同的元素,您将最终追加该元素。向前看,如果
unique
中有更多的元素,并且由于内部
for
循环没有“中断”而不同,那么您将多次追加它。这不是您想要的,您想要附加的元素等于
unique
none

还请注意,如果Go中的
struct
的每个字段都是可比较的,那么它是可比较的。由于您的
visit
结构只包含2个
int
字段,因此它是可比较的,因此您可以使用
=
操作符简单地比较
visit
类型的值,而无需使用丑陋的
reflect.DeepEqual()
。见:

如果结构值的所有字段都具有可比性,则结构值具有可比性。如果两个结构值对应的非字段相等,则两个结构值相等

下面是一个应用您的逻辑的简化、正确的版本:

visited := []visit{
    visit{1, 100},
    visit{2, 2},
    visit{1, 100},
    visit{1, 1},
}
var unique []visit

for _, v := range visited {
    skip := false
    for _, u := range unique {
        if v == u {
            skip = true
            break
        }
    }
    if !skip {
        unique = append(unique, v)
    }
}

fmt.Println(unique)
输出(在上尝试):

可供替代的 Go确实没有内置的集合类型,但您可以轻松地将
map[visit]bool
作为集合使用。这样,事情就变得非常简单了!请注意,
visit
可以用作地图中的键,因为它具有可比性(见上文)

输出(在上尝试):

唯一的“列表”是地图中的键列表

如果要将唯一的
visit
值作为一个切片,请参阅此变量:

var unique []visit
m := map[visit]bool{}

for _, v := range visited {
    if !m[v] {
        m[v] = true
        unique = append(unique, v)
    }
}

fmt.Println(unique)
输出(如预期,请在上尝试):

请注意,此索引表达式:
m[v]
的计算结果为
true
,如果
v
已在映射中(作为键,
true
是我们存储在映射中的值)。如果
v
尚未在映射中,则
m[v]
为类型
bool
生成值类型的零值,该值类型为
false
,正确地告知值
v
尚未在映射中。见:

对于
M

…如果映射为
nil
或不包含此类条目,
a[x]
M

我想你可以多参观几次。 像这样的

visited := make(map[visit]Boolean)
然后您可以设置访问的值

visited[visit]=true
最后,您可以通过此代码获取所有访问过的位置

for k, _ := range visited {
    unique = append(unique, k)
}

我想你可以借助地图来解决这个难题


非常感谢您的指导、反馈和修改。就像我说的,我是新手。再次感谢!如果希望列表只包含唯一的条目,通常可以执行类似于
map[string]struct{}{}
的操作。空结构不会占用任何内存。
[{1 100} {2 2} {1 1}]
visited := make(map[visit]Boolean)
visited[visit]=true
for k, _ := range visited {
    unique = append(unique, k)
}
package main

import (
    "fmt"
)

type visit struct {
    x, y int
}

func main() {
    var visited []visit
    var unique []visit

    uniqueMap := map[visit]int{}

    visited = append(visited, visit{1, 100})
    visited = append(visited, visit{2, 2})
    visited = append(visited, visit{1, 100})
    visited = append(visited, visit{1, 1})

    for _, v := range visited {
        if _, exist := uniqueMap[v]; !exist {
            uniqueMap[v] = 1
            unique = append(unique, v)
        } else {
            uniqueMap[v]++
        }
    }
    fmt.Printf("Uniques: %v\nMaps:%v\n", unique, uniqueMap)
}