Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A nice version for Vec<Vec<T>>.get?

Tags:

rust

Is there any comfortable way to get value from Vec<Vec<T>>? I can do it for a normal 1D Vec: vec.get(), but if vec is Vec<Vec>, get returns the Some<Vec<T>>, not the value of T. Is there a nice way to 'get' value from 2D matrix (Vec<Vec<T>>)?

like image 537
George Shuklin Avatar asked Jun 12 '26 08:06

George Shuklin


2 Answers

Option::and_then lets you chain optional return values (o.and_then(f) is equivalent to o.map(f).flatten()):

vec.get(i).and_then(|v| v.get(j))

It also easily extends to higher dimensions:

vec
    .get(i)
    .and_then(|v| v.get(j))
    .and_then(|v| v.get(k))
    .and_then(|v| v.get(l))
    // and so on
like image 124
Aplet123 Avatar answered Jun 15 '26 04:06

Aplet123


@Aplet123 is of course right, that's the way to go and his answer should be marked correct.

But in case you wonder how to make this prettier, you could wrap it in a custom trait for Vec<Vec<T>>:

trait Get2D {
    type Val;
    fn get2d(&self, i: usize, j: usize) -> Option<&Self::Val>;
    fn get2d_mut(&mut self, i: usize, j: usize) -> Option<&mut Self::Val>;
}

impl<T> Get2D for Vec<Vec<T>> {
    type Val = T;

    fn get2d(&self, i: usize, j: usize) -> Option<&T> {
        self.get(i).and_then(|e| e.get(j))
    }

    fn get2d_mut(&mut self, i: usize, j: usize) -> Option<&mut T> {
        self.get_mut(i).and_then(|e| e.get_mut(j))
    }
}

fn main() {
    let mut data: Vec<Vec<i32>> = vec![vec![1, 2, 3], vec![4, 5, 6]];

    println!("{}", data.get2d(1, 1).unwrap());

    *data.get2d_mut(0, 1).unwrap() = 42;

    println!("{:?}", data);
}
5
[[1, 42, 3], [4, 5, 6]]
like image 26
Finomnis Avatar answered Jun 15 '26 05:06

Finomnis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!