對於一個個人項目,我做了這樣的事情:
func filter(sl []int, fn func(int) bool) []int {
result := make([]int, 0, len(sl))
last := 0
for i, v := range sl {
if fn(v) {
result = append(result, sl[last:i]...)
last = i + 1
}
}
return append(result, sl[last:]...)
}
它不會發生變異的原創,但應該是比較有效的。 這可能是更好的做法:
func filter(sl []int, fn func(int) bool) (result []int) {
for _, v := range sl {
if !fn(v) {
result = append(result, v)
}
}
return
}
更簡單,更乾淨。 如果你想這樣做原地的,你可能想是這樣的:
func filter(sl []int, fn func(int) bool) []int {
outi := 0
res := sl
for _, v := range sl {
if !fn(v) {
res[outi] = v
outi++
}
}
return res[0:outi]
}
您可以優化該使用copy
複製元素的範圍,但是這兩次 的代碼,可能不值得。
因此,在這種特殊情況下,我可能會做這樣的事情:
func deleteRecords(l []*Record, ids []int) []*Record {
outi := 0
L:
for _, v := range l {
for _, id := range ids {
if v.id == id {
continue L
}
}
l[outi] = v
outi++
}
return l[0:outi]
}
(注:未經)
沒有撥款,沒有什麼花哨,並假設該列表的大小粗糙的記錄和您呈現的ID列表,一個簡單的線性搜索可能會做更好的事情,但沒有任何開銷。我意識到我的版本改變了分片和返回一個新分片,但這在Go中不是非慣用的,並且它避免了強制將分片放在callsite處。
append()可以在該循環的每次迭代中分配。 – Jessta 2011-02-16 21:43:34
我假設如果需要重新分配,append的容量就會增加一倍。儘管我在文檔中找不到它... – 2011-02-16 21:50:50
爲什麼不用`make([] RecordList,len(* l))``創建`newList`? – mkb 2011-02-16 21:53:33