在 JavaScript 中我会这样做:
function move(arr, old_index, new_index) {
while (old_index < 0) {
old_index += arr.length;
}
while (new_index < 0) {
new_index += arr.length;
}
if (new_index >= arr.length) {
var k = new_index - arr.length;
while ((k--) + 1) {
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
return arr;
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能在 Rust 中完成同样的事情?
我不想使用insertandremove因为我的向量是 astd::vec::Vec<std::string::String>并且我想将它们从字面上移动到向量中的不同位置,而不是删除它们然后插入副本。
我不想交换 2 个元素。我想将一个元素的索引更改为任意其他索引,就像一个人切到队列中的任意其他位置一样。
当您执行insert+ remove(或 JavaScript 中的 double splice)时,您将两个索引中较大的一个和数组末尾之间的所有项目移动两次:首先将它们向后移动一个位置remove,然后将它们向前移动一个位置为了insert。但这是不必要的。相反,您可以简单地截取一部分Vec并旋转它:
fn move_me(arr: &mut [String], old_index: usize, new_index: usize) {
if old_index < new_index {
arr[old_index..=new_index].rotate_left(1);
} else {
arr[new_index..=old_index].rotate_right(1);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,此更改允许move_metake&mut [String]代替&mut Vec<String>,这使得此代码更通用且更高效。最好接受&[T]而不是&Vec<T>,在这种情况下,相同的逻辑适用于&mut Vec<T>因为move_me不需要增大或缩小向量。
另外,正如在另一个答案中一样,我省略了使负索引从切片后面计数的部分,以及当索引太大时增加向量的部分,因为这些约定在惯用的 Rust 中都不常见。
| 归档时间: |
|
| 查看次数: |
1321 次 |
| 最近记录: |