在覆盖切片时从切片中移除项目的最佳方法是什么?
例如:
type MultiDataPoint []*DataPoint
func (m MultiDataPoint) Json() ([]byte, error) {
for i, d := range m {
err := d.clean()
if ( err != nil ) {
//Remove the DP from m
}
}
return json.Marshal(m)
}
Run Code Online (Sandbox Code Playgroud)
tom*_*asz 39
正如您在其他地方提到的那样,您可以分配新的内存块并仅将有效元素复制到其中.但是,如果要避免分配,可以就地重写切片:
i := 0 // output index
for _, x := range s {
if isValid(x) {
// copy and increment index
s[i] = x
i++
}
}
s = s[:i]
Run Code Online (Sandbox Code Playgroud)
完整示例:http://play.golang.org/p/FNDFswPeDJ
请注意,它会i在基础数组中的索引之后留下一些垃圾,因此请确保没有其他切片使用elswhere.
Mic*_*ael 14
可能有更好的方法,但这是一个从切片中删除偶数值的示例:
m := []int{1,2,3,4,5,6}
deleted := 0
for i := range m {
j := i - deleted
if (m[j] & 1) == 0 {
m = m[:j+copy(m[j:], m[j+1:])]
deleted++
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我没有使用i, d := range m语法获取元素,因为d一旦开始从切片中删除,最终会被设置为错误的元素.
aut*_*tic 12
我知道很久以前的答案,但我在其他语言中使用这样的东西,但我不知道它是否是golang方式.
只需从后向前迭代,这样您就不必担心被删除的索引.我使用与Adam相同的例子.
m = []int{3, 7, 2, 9, 4, 5}
for i := len(m)-1; i >= 0; i-- {
if m[i] < 5 {
m = append(m[:i], m[i+1:]...)
}
}
Run Code Online (Sandbox Code Playgroud)
另一个选项是使用切片长度的正常for循环,并在每次删除值时从索引中减去1.请参阅以下示例:
m := []int{3, 7, 2, 9, 4, 5}
for i := 0; i < len(m); i++ {
if m[i] < 5 {
m = append(m[:i], m[i+1:]...)
i-- // -1 as the slice just got shorter
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道是否len()使用了足够的资源来做出任何改变,但你也可以只运行一次并从长度值中减去:
m := []int{3, 7, 2, 9, 4, 5}
for i, s := 0, len(m); i < s; i++ {
if m[i] < 5 {
m = append(m[:i], m[i+1:]...)
s--
i--
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
这是从切片中删除元素的更惯用的 Go 方法。
temp := s[:0]
for _, x := range s {
if isValid(x) {
temp = append(temp, x)
}
}
s = temp
Run Code Online (Sandbox Code Playgroud)
游乐场链接:https : //play.golang.org/p/OH5Ymsat7s9
注意:示例和游乐场链接基于@tomasz 的回答/sf/answers/1438578151/
| 归档时间: |
|
| 查看次数: |
19825 次 |
| 最近记录: |