# How to slice a vector without using its length?

I've a `frames: Vec<Vec<u16>>`, where the inner vector can have either 1 or 2 elements. I want to take 2 elements starting at index `i`, for which the following possibilities exist:

1. `frames[i]` has 2 elements and there's no `frames[i+1]`.
2. `frames[i]` has 1 element and `frames[i+1]` has 1 element.
3. `frames[i]` has 1 element and `frames[i+1]` has 2 elements.
4. `frames[i]` has 2 elements and `frames[i+1]` has 1 element.
5. `frames[i]` has 2 elements and `frames[i+1]` has 2 elements.

I've come up with the following options:

Option 1:

``````frames[i]
.iter()
.chain(frames.get(i + 1).unwrap_or(&vec![]).iter())
.take(2)
``````

Option 2:

``````frames
[i..cmp::min(i + 2, frames.len())]
.iter()
.flat_map(|f| f.iter())
.take(2)
``````

It'd be nice if I could do ` frames[i..i + 2]` (or the `get` call) without worrying about the length, but it throws out of bounds exception. Some other languages, like Python and Go, would return the remaining of the slice if the end index is out of bounds, but Rust doesn't. Is there a cleaner way to do this?

You can do:

``````frames
[i..] // <-- no end bound here
.iter()
.flat_map(|f| f.iter())
.take(2)
``````
1 Like

To ensure you'll have no "out of bounds exception" (panic), you can adapt @tuxmain's code to avoid slicing and instead to use iterator methods only:

``````frames
.iter()
.skip(i)
.flat_map(|f| f.iter())
.take(2)
``````
1 Like

I think that `.flat_map(|f| f.iter())` can be replaced by `.flatten()` here (haven't tested it though).

Sadly, no, I just tried. `flatten` is for an `Iterator<Iterator>>` while we have here an `Iterator<Vec>>`.

It's `Iterator<Item=IntoIterator>`. This works:

``````    let iter = frames   // Vec<Vec<u16>>
.get(i..)       // Option<&[Vec<u16>]>
.into_iter()    // Iterator<Item=&[Vec<u16>]> (length 0 or 1)
.flatten()      // Iterator<Item=&Vec<u16>>   (frames[i..].iter())
.flatten()      // Iterator<Item=&u16>
.take(2);

for item in iter {
println!("{item}");
}
``````

Playground.

5 Likes