Search code examples
arraysrustmutable

How divide the mutable array into mutable subarrays


I need to divide the mutablearray into 3 mutablesubarrays with mutable elements.

#[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>>();
}

Next, over each subarray to carry out different manipulations that do not affect the main array. (For example, each subarray is first sorted without affecting the order of the main array. The next step is to manipulate its elements over each subarray. And these changes should be reflected in the elements of the main array).

At the moment, when dividing the array Rust when compiling, it gives the following error:

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

Solution

  • You can use Iterator::partition to split up your vec into two distinct vecs without cloning the inner elements. Because you want three different splits, you have to use partition twice (the order doesn't matter).

    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);
    

    (playground)

    Because the Vectors greater, equal and less own the corresponding elements, you have mutable access to them.