Arrays 删除GO lang中的元素并将其添加到数组中
我有两个数组声明为:Arrays 删除GO lang中的元素并将其添加到数组中,arrays,go,append,slice,Arrays,Go,Append,Slice,我有两个数组声明为: var输入[]字符串和var输出[]字符串 输入数组最初由一些ID填充。输出数组为空 在每次迭代之后,我想从输入数组中删除一个随机元素,并将其添加到输出数组中 最后,输出数组中的所有元素都将与输入数组相同(但顺序(索引)不同) 索引的:=0;指数
var输入[]字符串
和var输出[]字符串
输入数组最初由一些ID填充。输出数组为空
在每次迭代之后,我想从输入数组中删除一个随机元素,并将其添加到输出数组中
最后,输出数组中的所有元素都将与输入数组相同(但顺序(索引)不同)
索引的:=0;指数
当我尝试这样做时,我会得到
数组越界错误
对于输出
数组,您需要使用追加
或分配初始容量以匹配输入
的大小
// before the loop
output := make([]string, len(input))
这是我的建议,因为append
会导致大量不必要的重新分配,而且您已经知道需要什么容量,因为它基于输入
// before the loop
output := make([]string, len(input))
另一件事是:
output = append(output, input[index])
但正如我所说,从我观察到的情况来看,append的初始容量呈指数增长。如果您没有指定任何内容,这意味着在达到所需容量之前要进行几次不必要的重新分配,那么这将是基数2。您可以在中找到一些有用的技巧
自从引入内置的append
以来,在Go 1中删除的容器/向量
包的大部分功能都可以使用append
和copy
进行复制
以下是向量方法及其切片操作类似物:
附加向量
复制
削减
删除
删除而不保留顺序
a[i] = a[len(a)-1]
a = a[:len(a)-1]
注意如果元素的类型是指针或带有指针字段的结构,需要进行垃圾收集,则上述Cut
和Delete
的实现可能存在内存泄漏问题:具有值的某些元素仍然被slicea
引用,因此无法收集。以下代码可以解决此问题:
切割
删除而不保留顺序
a[i] = a[len(a)-1]
a = a[:len(a)-1]
扩大
延伸
插入
注意第二个append
创建了一个具有自己底层存储的新切片,并将a[i:
中的元素复制到该切片,然后将这些元素复制回切片a
(通过第一个append
)。通过使用另一种方法,可以避免创建新的片(以及内存垃圾)和第二个副本:
插入
插入向量
流行音乐
弹回
推
向前推
移位
取消移位
附加技巧
过滤而不分配
这个技巧利用了一个事实,即一个片与原始片共享相同的备份阵列和容量,因此存储被重新用于过滤后的片。当然,原始内容会被修改
b := a[:0]
for _, x := range a {
if f(x) {
b = append(b, x)
}
}
颠倒
要使用相同的元素(但顺序相反)替换切片的内容,请执行以下操作:
for i := len(a)/2-1; i >= 0; i-- {
opp := len(a)-1-i
a[i], a[opp] = a[opp], a[i]
}
同样的事情,除了两个指数:
for left, right := 0, len(a)-1; left < right; left, right = left+1, right-1 {
a[left], a[right] = a[right], a[left]
}
有没有一种方法可以在不重新分配的情况下附加到切片?
copy(a[i:], a[j:])
for k, n := len(a)-j+i, len(a); k < n; k++ {
a[k] = nil // or the zero value of T
}
a = a[:len(a)-j+i]
copy(a[i:], a[i+1:])
a[len(a)-1] = nil // or the zero value of T
a = a[:len(a)-1]
a[i] = a[len(a)-1]
a[len(a)-1] = nil
a = a[:len(a)-1]
a = append(a[:i], append(make([]T, j), a[i:]...)...)
a = append(a, make([]T, j)...)
a = append(a[:i], append([]T{x}, a[i:]...)...)
s = append(s, 0)
copy(s[i+1:], s[i:])
s[i] = x
a = append(a[:i], append(b, a[i:]...)...)
x, a = a[0], a[1:]
x, a = a[len(a)-1], a[:len(a)-1]
a = append(a, x)
a = append([]T{ x }, a...)
x, a := a[0], a[1:]
a = append([]T{x}, a...)
b := a[:0]
for _, x := range a {
if f(x) {
b = append(b, x)
}
}
for i := len(a)/2-1; i >= 0; i-- {
opp := len(a)-1-i
a[i], a[opp] = a[opp], a[i]
}
for left, right := 0, len(a)-1; left < right; left, right = left+1, right-1 {
a[left], a[right] = a[right], a[left]
}
for i := len(a) - 1; i > 0; i-- {
j := rand.Intn(i + 1)
a[i], a[j] = a[j], a[i]
}