英文:
How can I create an array that contains unique strings?
问题
你可以使用map来创建一个包含唯一字符串的数组。以下是你的代码示例的修改版本:
var paths = make(map[string]bool)
func main() {
// Members are added dynamically
paths["aaa"] = true
paths["bbb"] = true
paths["bbb"] = true
paths["ccc"] = true
// Convert map keys to a slice
uniquePaths := make([]string, 0, len(paths))
for key := range paths {
uniquePaths = append(uniquePaths, key)
}
}
在这个修改后的代码中,我们使用了一个map来存储唯一的字符串。map的键是字符串,值是布尔类型。当你想要添加一个新的字符串时,你只需要将它作为键添加到map中即可。由于map的键是唯一的,重复的字符串将被自动去重。
最后,我们将map的键转换为一个切片,以便你可以继续使用它。在循环中,我们遍历map的键,并将它们逐个添加到切片中。这样,你就得到了一个包含唯一字符串的切片uniquePaths
。
英文:
I want to create an array that contains unique strings. How can I do that?
var paths = make([]string, 0)
func main() {
// Members are added dynamically
paths = append(paths, "aaa")
paths = append(paths, "bbb")
paths = append(paths, "bbb")
paths = append(paths, "ccc")
// convert ["aaa", "bbb", "bbb", "ccc"] -> ["aaa", "bbb", "ccc"]
// or can I use some class that disallow the same string automaticaly?
}
答案1
得分: 34
如果你想要一个包含唯一元素的集合,可以使用集合(Set)数据类型。Go语言没有内置的集合数据类型,但你可以使用map来充当集合:map中的键必须是唯一的。
对于一个“好看”的集合,可以使用值类型为bool
的map(值为true
),并利用零值(zero value)特性。如果想要占用最小的内存空间,可以使用值类型为struct{}
的map,因为struct{}
类型的值不占用内存空间;并且可以使用逗号-OK惯用法来判断一个值是否在集合/映射中。
下面是一个“好看”版本的集合示例。将元素添加到map[string]bool
中,作为键,值为true
:
m := make(map[string]bool)
m["aaa"] = true
m["bbb"] = true
m["bbb"] = true
m["ccc"] = true
要检查一个元素是否已经在集合(映射)中,可以简单地使用索引表达式:
exists := m["somevalue"]
这利用了零值特性,即如果映射中还没有包含该元素,那么值类型的零值将被返回,对于bool
类型来说,返回false
,正确地表示该元素不在集合中。
映射中的元素没有固定的顺序。如果需要保持顺序(例如插入顺序),可以使用切片(用于记住顺序)和映射(用于判断要添加的元素是否是新元素)。可以使用一个辅助的add()
函数来实现:
var m = make(map[string]bool)
var a = []string{}
func main() {
add("aaa")
add("bbb")
add("bbb")
add("ccc")
}
func add(s string) {
if m[s] {
return // 已经在映射中
}
a = append(a, s)
m[s] = true
}
英文:
If you want a collection of unique elements, that is the Set data type. Go does not have a builtin set data type, but you can use a map to act as a set: keys in a map must be unique.
For a "nice" set, use a map with bool
value type (with true
values) and exploit the zero value. For a set with the smallest memory footprint, use a map with struct{}
value type as values of struct{}
type occupy no memory; and use the comma-ok idiom to tell if a value is in the set / map.
Here's how the "nice" version of set looks like. Instead of a slice add your elements to a map[string]bool
as the key with a true
as the value:
m := make(map[string]bool)
m["aaa"] = true
m["bbb"] = true
m["bbb"] = true
m["ccc"] = true
To check if an element is already in the collection (map), you can simply use an index expression:
exists := m["somevalue"]
This exploits the zero value, that is if the map does not yet contain an element, the zero value of the value type is returned which is false
in case of bool
type, properly indicating that the element is not in the collection.
Elements in a map have no fixed order. If you need to keep the order (e.g. insertion order), then use a slice (to remember the order) and a map (to tell if an element to be added is new). This is easiest with a helper add()
function:
var m = make(map[string]bool)
var a = []string{}
func main() {
add("aaa")
add("bbb")
add("bbb")
add("ccc")
}
func add(s string) {
if m展开收缩 {
return // Already in the map
}
a = append(a, s)
m展开收缩 = true
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论