对于一个个人项目,我做了这样的事情:
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