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>>)?
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
#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]]
Related
I have a function that splits a slice into three parts, a leading and trailing slice, and a reference to the middle element.
/// The leading and trailing parts of a slice.
struct LeadingTrailing<'a, T>(&'a mut [T], &'a mut [T]);
/// Divides one mutable slice into three parts, a leading and trailing slice,
/// and a reference to the middle element.
pub fn split_at_rest_mut<T>(x: &mut [T], index: usize) -> (&mut T, LeadingTrailing<T>) {
debug_assert!(index < x.len());
let (leading, trailing) = x.split_at_mut(index);
let (val, trailing) = trailing.split_first_mut().unwrap();
(val, LeadingTrailing(leading, trailing))
}
I would like to implement Iterator for LeadingTrailing<'a, T> so that it first iterates over the first slice, and then over the second. i.e., it will behave like:
let mut foo = [0,1,2,3,4,5];
let (item, lt) = split_at_rest_mut(&foo, 2);
for num in lt.0 {
...
}
for num in lt.1 {
...
}
I have tried converting to a Chain:
struct LeadingTrailing<'a, T>(&'a mut [T], &'a mut [T]);
impl <'a, T> LeadingTrailing<'a, T> {
fn to_chain(&mut self) -> std::iter::Chain<&'a mut [T], &'a mut [T]> {
self.0.iter_mut().chain(self.1.iter_mut())
}
}
But I get the error:
89 | self.0.iter_mut().chain(self.1.iter_mut())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&mut [T]`, found struct `std::slice::IterMut`
I have also tried creating a custom Iterator
/// The leading and trailing parts of a slice.
struct LeadingTrailing<'a, T>(&'a mut [T], &'a mut [T]);
struct LTOthersIterator<'a, T> {
data: LeadingTrailing<'a, T>,
index: usize,
}
/// Iterates over the first slice, then the second slice.
impl<'a, T> Iterator for LTOthersIterator<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
let leading_len = self.data.0.len();
let trailing_len = self.data.1.len();
let total_len = leading_len + trailing_len;
match self.index {
0..=leading_len => {
self.index += 1;
self.data.0.get(self.index - 1)
}
leading_len..=total_len => {
self.index += 1;
self.data.1.get(self.index - leading_len - 1)
}
}
}
}
But I get the error:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src\main.rs:104:29
|
104 | self.data.0.get(self.index - 1)
^^^
What is the correct way to do this?
You either let the compiler do the work:
impl <'a, T> LeadingTrailing<'a, T> {
fn to_chain(&mut self) -> impl Iterator<Item = &mut T> {
self.0.iter_mut().chain(self.1.iter_mut())
}
}
Or perscribe the correct type, Chain takes the iterators, not the thing they got created from.
impl <'a, T> LeadingTrailing<'a, T> {
fn to_chain(&'a mut self) -> std::iter::Chain<std::slice::IterMut<'a, T>, std::slice::IterMut<'a, T>> {
self.0.iter_mut().chain(self.1.iter_mut())
}
}
The return value of to_chain() is incorrect.
For simplicity, just use impl Iterator.
/// The leading and trailing parts of a slice.
#[derive(Debug)]
pub struct LeadingTrailing<'a, T>(&'a mut [T], &'a mut [T]);
/// Divides one mutable slice into three parts, a leading and trailing slice,
/// and a reference to the middle element.
pub fn split_at_rest_mut<T>(x: &mut [T], index: usize) -> (&mut T, LeadingTrailing<T>) {
debug_assert!(index < x.len());
let (leading, trailing) = x.split_at_mut(index);
let (val, trailing) = trailing.split_first_mut().unwrap();
(val, LeadingTrailing(leading, trailing))
}
impl<T> LeadingTrailing<'_, T> {
fn to_chain(&mut self) -> impl Iterator<Item = &mut T> {
self.0.iter_mut().chain(self.1.iter_mut())
}
}
fn main() {
let mut arr = [0, 1, 2, 3, 4, 5, 6, 7, 8];
let (x, mut leadtrail) = split_at_rest_mut(&mut arr, 5);
println!("x: {}", x);
println!("leadtrail: {:?}", leadtrail);
for el in leadtrail.to_chain() {
*el *= 2;
}
println!("leadtrail: {:?}", leadtrail);
}
x: 5
leadtrail: LeadingTrailing([0, 1, 2, 3, 4], [6, 7, 8])
leadtrail: LeadingTrailing([0, 2, 4, 6, 8], [12, 14, 16])
The fully written out version would be:
impl<T> LeadingTrailing<'_, T> {
fn to_chain(&mut self) -> std::iter::Chain<std::slice::IterMut<T>, std::slice::IterMut<T>> {
self.0.iter_mut().chain(self.1.iter_mut())
}
}
My intention is to create a dynamic 2D array with multiple rows and columns. How can I achieve that?
Attempted solution
The following line of code works but the array ends up having only a single row.
let matrix: &mut [&mut [i32]] = &mut [&mut [0; 3]];
In order to create an array with 3 rows instead of one I tried the following piece of code but it produced a compile time error.
let matrix: &mut [&mut [i32]] = &mut [&mut [0; 3]; 3];
mismatched types
expected slice `[&mut [i32]]`, found array `[&mut [{integer}; 3]; 3]`
note: expected mutable reference `&mut [&mut [i32]]`
found mutable reference `&mut [&mut [{integer}; 3]; 3]`rustc(E0308)
main.rs(7, 17): expected due to this
main.rs(7, 37): expected slice `[&mut [i32]]`, found array `[&mut [{integer}; 3]; 3]`
Based on your question it looks like you're trying to use a matrix object.
There are multiple ways to do that in rust:
Compile-Time matrices:
Using const generics it's now very easy to define the matrix object with an array of arrays:
pub struct Matrix<T, const ROWS: usize, const COLS: usize> {
data: [[T; COLS]; ROWS],
}
impl<T, const ROWS: usize, const COLS: usize> Matrix<T, ROWS, COLS> {
pub fn new(data: [[T; COLS]; ROWS]) -> Self {
Self { data }
}
}
impl<T, const ROWS: usize, const COLS: usize> Index<(usize, usize)> for Matrix<T, ROWS, COLS> {
type Output = T;
fn index(&self, index: (usize, usize)) -> &Self::Output {
&self.data[index.0][index.1]
}
}
Here, the amount of rows and columns are hard-coded into the data-type.
So to resize you need to a create a new object and all types must be known (defined) at compile time.
Dynamic matrices:
If you want run-time (dynamic) sizing, the simplest solution is to use a vector of vectors:
pub struct Matrix<T> {
data: Vec<Vec<T>>,
}
impl<T> Matrix<T> {
pub fn new(data: Vec<Vec<T>>) -> Self {
Self { data }
}
}
impl<T> Index<(usize, usize)> for Matrix<T> {
type Output = T;
fn index(&self, index: (usize, usize)) -> &Self::Output {
&self.data[index.0][index.1]
}
}
Note that since vectors are pointers to memory on the heap, the items won't usually be contiguous in memory.
You can build contiguous dynamic matrices by using a single vector and indices to map to chunks of it:
pub struct Matrix<T> {
rows: usize,
cols: usize,
data: Vec<T>,
}
impl<T> Matrix<T> {
pub fn new(rows: usize, cols: usize, data: Vec<T>) -> Self {
assert_eq!(rows * cols, data.len());
Self { rows, cols, data }
}
}
impl<T> Index<(usize, usize)> for Matrix<T> {
type Output = T;
fn index(&self, index: (usize, usize)) -> &Self::Output {
&self.data[index.0 * self.cols + index.1]
}
}
I want to write a function that process some slices in different order, so I decided to write a function that is generic over the iterating order, something like:
fn foo<'a, I: Iterator<Item = &'a mut i32>>(make_iter: impl Fn(&'a mut [i32]) -> I) {
let mut data = [1, 2, 3, 4];
make_iter(&mut data);
}
fn main() {
foo(|x| x.iter_mut());
foo(|x| x.iter_mut().rev());
}
This causes “borrowed value does not live long enough” error.
I imagine something like
fn foo(make_iter: impl for<'a> Fn(&'a mut [i32]) -> impl Iterator<Item = &'a mut i32>) {
let mut data = [1, 2, 3, 4];
make_iter(&mut data);
}
should be used, but impl Iterator is not allow at that position. So is there anything I can do?
Update:
The slices to to processed should be considered dynamically generated inside the foo function, and are dropped after processing.
Your function is mostly correct. The compiled error "borrowed value does not live long enough" is due to the fact that you are defining your data inside the foo rather than pass it in. The error is because of the linelet mut data = [1, 2, 3, 4];
The life time of the data is same as the function foo because it is created in the function foo. However, the closure's life time is longer than the variable data as the closure is passed in as an argument to foo so its lifetime is longer than data. When the function foo goes out of the scope, the data is dropped. Then your closure's is trying to return a reference data which is already dropped. This is why you have compiled error "borrowed value does not live long enough".
You can make this compile by passing the data into foo as an argument, in this case, you will not have the issue due to lifetime.
The below code will compile.
fn foo<'a, I: Iterator<Item = &'a mut i32>>(make_iter: impl Fn(&'a mut [i32]) -> I, data: &'a mut Vec<i32>) {
// let mut data = [1, 2, 3, 4];
make_iter(data);
}
fn main() {
let mut data= vec![1,2,3,4];
foo(|x| x.iter_mut(), &mut data);
foo(|x| x.iter_mut().rev(), &mut data);
}
The rustplay ground link : https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8b263451fcb01518b3f35bda8485af9c
Update: Sry to misunderstand your requirements. I was trying to come out a clean way to write this, but the best I can come up with is using Box<dyn to do. I know there are runtime cost for Box<dyn..., but I can't come out a better way using impl Iterator
The implementation using Box<dyn ... is
fn foo<F>(make_iter: F) where for<'a> F: Fn(&'a mut [i32])->Box<dyn Iterator<Item=&'a mut i32>+'a>{
let mut data = vec![1, 2, 3, 4];
make_iter(&mut data);
}
fn main() {
foo(|x| Box::new(x.iter_mut()));
foo(|x| Box::new(x.iter_mut().rev()));
}
I came up with one solution:
use std::iter::Rev;
use std::slice::IterMut;
trait MakeIter<'a> {
type Iter: Iterator<Item = &'a mut i32>;
fn make_iter(&mut self, slice: &'a mut [i32]) -> Self::Iter;
}
fn foo(mut make_iter: impl for<'a> MakeIter<'a>) {
let mut data = [1, 2, 3, 4];
make_iter.make_iter(&mut data);
}
struct Forward;
impl<'a> MakeIter<'a> for Forward {
type Iter = IterMut<'a, i32>;
fn make_iter(&mut self, slice: &'a mut [i32]) -> Self::Iter {
slice.iter_mut()
}
}
struct Backward;
impl<'a> MakeIter<'a> for Backward {
type Iter = Rev<IterMut<'a, i32>>;
fn make_iter(&mut self, slice: &'a mut [i32]) -> Self::Iter {
slice.iter_mut().rev()
}
}
fn main() {
foo(Forward);
foo(Backward);
}
But I am not sure whether it can be simplified.
Update
Here is a simplification:
trait MakeIter<'a> {
type Iter: Iterator<Item = &'a mut i32>;
fn make_iter(&mut self, slice: &'a mut [i32]) -> Self::Iter;
}
fn foo(mut make_iter: impl for<'a> MakeIter<'a>) {
let mut data = [1, 2, 3, 4];
make_iter.make_iter(&mut data);
}
impl<'a, F, R> MakeIter<'a> for F
where
F: FnMut(&'a mut [i32]) -> R,
R: Iterator<Item = &'a mut i32>,
{
type Iter = R;
fn make_iter(&mut self, slice: &'a mut [i32]) -> Self::Iter {
self(slice)
}
}
fn iter_forward(slice: &mut [i32]) -> impl Iterator<Item = &mut i32> {
slice.iter_mut()
}
fn iter_backward(slice: &mut [i32]) -> impl Iterator<Item = &mut i32> {
slice.iter_mut().rev()
}
fn main() {
foo(iter_forward);
foo(iter_backward);
}
I want to iterate over clients in a Vec and process each using a method that is supposed to take all the other clients as an argument as well.
There's no such iterator that I'm aware of, but it's not complicated to create your own:
struct X<'a, T: 'a> {
item: &'a T,
before: &'a [T],
after: &'a [T],
}
struct AllButOne<'a, T: 'a> {
slice: &'a [T],
index: usize,
}
impl<'a, T> AllButOne<'a, T> {
fn new(slice: &'a [T]) -> Self {
AllButOne { slice, index: 0 }
}
}
impl<'a, T> Iterator for AllButOne<'a, T> {
type Item = X<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.index > self.slice.len() {
return None;
}
let (before, middle) = self.slice.split_at(self.index);
let (middle, after) = middle.split_at(1);
self.index += 1;
Some(X {
before,
after,
item: &middle[0],
})
}
}
fn main() {
let a = [1, 2, 3, 4];
for x in AllButOne::new(&a) {
println!("{:?}, {}, {:?}", x.before, x.item, x.after);
}
}
[], 1, [2, 3, 4]
[1], 2, [3, 4]
[1, 2], 3, [4]
[1, 2, 3], 4, []
This returns two slices, one for all the values before the current item and one for after. You can perform allocation and stick them into the same collection if you need.
Does the standard library provide a way to split a slice [T] using another slice of the same type as a delimiter? The library's documentation lists methods that operate on single-element delimiters rather than slices.
For example: A slice of 5 u64 integers [1u64, 4u64, 0u64, 0u64, 8u64] split using [0u64, 0u64] as a delimiter would result in two slices [1u64, 4u64] and [8u64].
Does the standard library provide a way to split a slice [T] using another slice of the same type as a delimiter?
As of Rust 1.9, no, but you can implement it:
fn main() {
let a = [1, 4, 7, 0, 0, 8, 10, 0, 0];
let b = [0, 0];
let mut iter = split_subsequence(&a, &b);
assert_eq!(&[1, 4, 7], iter.next().unwrap());
assert_eq!(&[8, 10], iter.next().unwrap());
assert!(iter.next().unwrap().is_empty());
assert_eq!(None, iter.next());
}
pub struct SplitSubsequence<'a, 'b, T: 'a + 'b> {
slice: &'a [T],
needle: &'b [T],
ended: bool,
}
impl<'a, 'b, T: 'a + 'b + PartialEq> Iterator for SplitSubsequence<'a, 'b, T> {
type Item = &'a [T];
fn next(&mut self) -> Option<Self::Item> {
if self.ended {
None
} else if self.slice.is_empty() {
self.ended = true;
Some(self.slice)
} else if let Some(p) = self.slice
.windows(self.needle.len())
.position(|w| w == self.needle) {
let item = &self.slice[..p];
self.slice = &self.slice[p + self.needle.len()..];
Some(item)
} else {
self.ended = true;
let item = self.slice;
self.slice = &self.slice[self.slice.len() - 1..];
Some(item)
}
}
}
fn split_subsequence<'a, 'b, T>(slice: &'a [T], needle: &'b [T]) -> SplitSubsequence<'a, 'b, T>
where T: 'a + 'b + PartialEq
{
SplitSubsequence {
slice: slice,
needle: needle,
ended: false,
}
}
Note that this implementation uses a naive algorithm for finding an equal subsequence.