How can I create an array that contains unique strings?

huangapple go评论95阅读模式
英文:

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 }

huangapple
  • 本文由 发表于 2015年10月19日 13:27:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/33207197.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定