kirin
kirin

Reputation: 1960

How to get mutable slice with conditions in Rust

I'd like to write something similar with following code in Rust.

fn main() {
    let mut v: Vec<i64> = vec![1, 2, 3, 4, 5];
    let mut s: Vec<&mut i64> = v
        .iter_mut()
        .filter(|val| **val < 2_i64)
        .collect();
    if s.len() == 0 {
        s = v
            .iter_mut()
            .filter(|val| **val > 2_i64)
            .collect();
    }
    *s[0] = 0;
    println!("{:?}", v);
}

It's obviously making borrowing reference twice. I know it causes an error, E0384: cannot assign twice to immutable variable s cannot assign twice to immutable variable.

Could you tell me how to write this kind of work flow in Rust? I want to filter value and if it returns nothing, apply another filter and get Vec of borrowing reference.

I tried to use shared reference. After filtered the Vec, I needed to convert shared reference to borrowing one, but it was not possible.

Upvotes: 3

Views: 602

Answers (2)

Kartikeya Sharma
Kartikeya Sharma

Reputation: 553

We can clone the reference like this:

fn main() {
    let mut v: Vec<i64> = vec![1, 2, 3, 4, 5];
    let mut t = v.clone();
    let mut s: Vec<&mut i64> = v.iter_mut().filter(|val| **val < 2_i64).collect();
    if s.len() == 0 {
        s = t.iter_mut().filter(|val| **val > 2_i64).collect();
    }
    *s[0] = 0;
    println!("{:?}", v);
}

Upvotes: 0

Boiethios
Boiethios

Reputation: 42739

You can write something like that. I agree that it's not really beautiful, but it works:

fn main() {
    let mut v = vec![1_i64, 2, 3, 4, 5];
    let s: Vec<_> = v.iter_mut().filter(|&val| *val < 2).collect();
    let mut s = if s.len() == 0 {
        v.iter_mut().filter(|&val| *val > 2).collect()
    } else {
        s
    };

    *s[0] = 0;
    println!("{:?}", v);
}

Upvotes: 2

Related Questions