提问人:TupleCats 提问时间:12/13/2018 最后编辑:Peter HallTupleCats 更新时间:12/20/2018 访问量:1364
如何将可变数组划分为可变子数组
How divide the mutable array into mutable subarrays
问:
我需要将 mutablearray 划分为 3 个具有可变元素的 mutablesubarray。
#[derive(Debug)]
struct Server {
time: i64
}
impl Server {
fn new(x: i64) -> Server {
return Server {
time: x
}
}
}
fn main() {
let mut arr = Vec::<Server>::new();
arr.push(Server::new(10));
arr.push(Server::new(20));
arr.push(Server::new(30));
arr.push(Server::new(40));
arr.push(Server::new(50));
let mut arr1 = arr.iter_mut().filter(|x| x.time > 20).collect::<Vec<&mut Server>>();
let mut arr2 = arr.iter_mut().filter(|x| x.time < 20).collect::<Vec<&mut Server>>();
let mut arr3 = arr.iter_mut().filter(|x| x.time == 20).collect::<Vec<&mut Server>>();
}
接下来,对每个子阵列执行不影响主阵列的不同操作。(例如,首先对每个子数组进行排序,而不会影响主数组的顺序。下一步是在每个子数组上操作其元素。这些变化应该反映在主数组的元素中)。
目前,在编译时划分数组 Rust 时,它给出了以下错误:
error[E0499]: cannot borrow `arr` as mutable more than once at a time
--> src/main.rs:26:18
|
25 | let mut arr1 = arr.iter_mut().filter(|x| x.time > 20).collect::<Vec<&mut Server>>();
| --- first mutable borrow occurs here
26 | let mut arr2 = arr.iter_mut().filter(|x| x.time < 20).collect::<Vec<&mut Server>>();
| ^^^ second mutable borrow occurs here
...
29 | }
| - first borrow ends here
error[E0499]: cannot borrow `arr` as mutable more than once at a time
--> src/main.rs:27:18
|
25 | let mut arr1 = arr.iter_mut().filter(|x| x.time > 20).collect::<Vec<&mut Server>>();
| --- first mutable borrow occurs here
26 | let mut arr2 = arr.iter_mut().filter(|x| x.time < 20).collect::<Vec<&mut Server>>();
27 | let mut arr3 = arr.iter_mut().filter(|x| x.time == 20).collect::<Vec<&mut Server>>();
| ^^^ second mutable borrow occurs here
28 |
29 | }
| - first borrow ends here
答:
3赞
hellow
12/13/2018
#1
您可以使用 Iterator::p artition
将 S 拆分为两个不同的元素,而无需克隆内部元素。
因为你想要三个不同的拆分,所以你必须使用两次(顺序无关紧要)。vec
vec
partition
const THRESHOLD: i64 = 20;
let mut arr = Vec::<Server>::new();
arr.push(Server::new(10));
arr.push(Server::new(20));
arr.push(Server::new(30));
arr.push(Server::new(40));
arr.push(Server::new(50));
let (greater, rest): (Vec<_>, Vec<_>) = arr.into_iter().partition(|s| s.time > THRESHOLD);
let (equal, less): (Vec<_>, Vec<_>) = rest.into_iter().partition(|s| s.time == THRESHOLD);
(操场)
因为 Vectors ,并且拥有相应的元素,所以您可以对它们进行可变访问。greater
equal
less
评论
0赞
hellow
12/13/2018
作为代码的注释:我建议使用 vec!
宏,而不是乏味的 ,例如push
let arr = vec![Server::new(10), Server::new(20), Server::new(30), Server::new(40), Server::new(50)];
1赞
Jmb
12/14/2018
但请注意,此答案将项目移动到迭代器中,因此它没有涵盖问题的最后一部分:这些更改应反映在主数组的元素中。
0赞
hellow
12/14/2018
@Jmb你是对的,但恐怕除了使用和一个简单的这是不可能的。我的解决方案显示了(恕我直言)如何处理此问题的最佳解决方案。为了反映对“主数组”的更改,我将再次将所有三个数组收集到一个数组中。RefCells
filter
0赞
TupleCats
12/14/2018
@hellow 我认为这个决定是错误的:为了反映对“主数组”的更改,我将再次将所有三个数组收集到一个数组中。因为我写过每个子数组都可以排序。也许唯一正确的方法是使用 和RefCells
filter
1赞
Boiethios
12/14/2018
let mut arr: Vec<_> = vec![10, 20, 30, 40, 50].into_iter().map(Server::new).collect();
也很酷。
评论
Vec<RefCell<Server>>
return
return Server { time: x }
Server { time: x }
分区
的实现非常简单,并且在不使用花哨的东西的情况下是最容易实现的解决方案。vec
unsafe
itertools::p artition
一样,但是一个 3 路分区。[T]::swap
使使用安全代码进行有效分区成为可能。是的,我熟悉 Rust。