在 Vec 的中间或开头有效地插入或替换多个元素? [英] Efficiently insert or replace multiple elements in the middle or at the beginning of a Vec?
问题描述
是否有任何直接的方法可以插入或替换来自 &[T]
和/或 Vec
中的多个元素?Vec
在线性时间内?
Is there any straightforward way to insert or replace multiple elements from &[T]
and/or Vec<T>
in the middle or at the beginning of a Vec
in linear time?
我只能找到 std::vec::Vec::insert
,但这只是为了在 O(n)
时间内插入单个元素,所以我显然不能在循环中调用它.
I could only find std::vec::Vec::insert
, but that's only for inserting a single element in O(n)
time, so I obviously cannot call that in a loop.
我可以在那个索引处做一个split_off
,extend
新元素到分裂的左半部分,然后 将后半部分扩展到前半部分,但有更好的方法吗?
I could do a split_off
at that index, extend
the new elements into the left half of the split, and then extend
the second half into the first, but is there a better way?
推荐答案
从 Rust 1.21.0 开始,Vec::splice
可用并允许在任何点插入,包括完全前置:
As of Rust 1.21.0, Vec::splice
is available and allows inserting at any point, including fully prepending:
let mut vec = vec![1, 5];
let slice = &[2, 3, 4];
vec.splice(1..1, slice.iter().cloned());
println!("{:?}", vec); // [1, 2, 3, 4, 5]
文档状态:
注意 4:这是最佳选择:
Note 4: This is optimal if:
- 尾部(范围后向量中的元素)为空
- 或
replace_with
产生的元素少于范围的长度 - 或其
size_hint()
的下限是精确的.
- The tail (elements in the vector after range) is empty
- or
replace_with
yields fewer elements than range’s length - or the lower bound of its
size_hint()
is exact.
在这种情况下,切片迭代器的下限应该是精确的,因此它应该执行一次内存移动.
In this case, the lower bound of the slice's iterator should be exact, so it should perform one memory move.
splice
更强大一点,它允许您删除一系列值(第一个参数),插入新值(第二个参数),并有选择地获取旧值(调用结果).
splice
is a bit more powerful in that it allows you to remove a range of values (the first argument), insert new values (the second argument), and optionally get the old values (the result of the call).
替换一组项目
let mut vec = vec![0, 1, 5];
let slice = &[2, 3, 4];
vec.splice(..2, slice.iter().cloned());
println!("{:?}", vec); // [2, 3, 4, 5]
获取以前的值
let mut vec = vec![0, 1, 2, 3, 4];
let slice = &[9, 8, 7];
let old: Vec<_> = vec.splice(3.., slice.iter().cloned()).collect();
println!("{:?}", vec); // [0, 1, 2, 9, 8, 7]
println!("{:?}", old); // [3, 4]
这篇关于在 Vec 的中间或开头有效地插入或替换多个元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!