有效地将切片插入另一个切片

Posted

技术标签:

【中文标题】有效地将切片插入另一个切片【英文标题】:Efficiently inserting a slice into another slice 【发布时间】:2018-05-30 12:07:12 【问题描述】:

在 Go 中,您可以将一个切片插入另一个切片的中间like this:

a = append(a[:i], append(b, a[i:]...)...)

但是,据我了解,首先将a[i:] 附加到b,方法是将其复制到b 的末尾(并可能重新分配b,然后然后复制整个切片到a,再次可能重新分配它。

这似乎有一个额外的副本和分配给你真正需要的东西。在 C++ 中,我会这样做(我的意思是......显然不使用 insert)。

// Reserve enough space in `a` for `a` and `b`.
a.reserve(a.size() + b.size());

// Move the second half of `a` to the end.
std::copy(a.begin() + i, a.end(), a.begin() + i + b.size());

// Copy `b` into the middle.
std::copy(b.begin(), b.end(), a.begin() + i);

在 Go 中有类似的方法吗?

【问题讨论】:

【参考方案1】:

假设有一个 int 切片,下面是 Go 的翻译:

// Reserve space for the combined length of the slices
c := make([]int, len(a)+len(b))

// Copy the first part of a to the beginning
copy(c, a[:i])

// Copy the last part of a to the end
copy(c[i+len(b):], a[i:])

// Copy b to the middle
copy(c[i:], b)

playground example

要利用a 的容量,请执行以下操作:

if cap(a) < len(a)+len(b) 
    // Not enough space, allocate new slice
    c := make([]int, len(a)+len(b))

    // Copy the first part of a to the beginning
    copy(c, a[:i])

    // Copy the last part of a to the end
    copy(c[i+len(b):], a[i:])

    a = c
 else 
    // reslice to combined length
    a = a[:len(a)+len(b)]

    // copy the last part of a to the end
    copy(a[i+len(b):], a[i:])


// copy b to the middle
copy(a[i:], b)

playground example

【讨论】:

以上是关于有效地将切片插入另一个切片的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地将树状数据结构插入 postgres

使用 AnyDAC (FireDAC) 从 SQLite 表中读取切片数据 (MBTiles) 的最有效方法是啥?

更新切片中的状态,将对象作为有效负载 [重复]

有效地使用多个 Numpy 切片进行随机图像裁剪

使用接口在非空数组(切片)中查找另一个“特殊”数组

为啥索引超出范围的子字符串切片有效?