Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I split a Vec to return a tuple of the item at the given index and the rest of the vector?

I want to iterate through a vector, and get a mutable reference to each item, and a mutable slice to the rest of the vector, so I can use both every iteration. Something like:

e.g:

for index in 0..model.len() {
    let (item, rest): (&mut Item, &mut [Item]) = model.split_rest_mut(index);
    item.do_something(rest);
}

e.g [1,2,3,4,5,6].split_rest_mut(2) would be 3, [1,2,4,5,6].

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I would like this to be as performant as possible.

It seems to be similar behaviour to split_at_mut, so I imagine this should be possible.

How would I go about doing this?

>Solution :

With the exact signature split_rest_mut(usize) -> (&mut T, &[T]), that is impossible: for an index which is neither for the first element nor the last element, the remaining elements are not contiguous in memory, and so cannot coexist in a single slice.

Instead, such a function would have to return two slices: one for the leading part of the slice and another one for the trailing part.

+-------------+-------------+--------------+
|  ...leading | middle item |  ...trailing |
+-------------+-------------+--------------+

Its implementation can be built with a combination of split_at_mut and split_first_mut.

pub fn split_at_rest_mut<T>(x: &mut [T], index: usize) -> (&mut T, &mut [T], &mut [T]) {
    assert!(index < x.len());
    // split in two
    let (leading, trailing) = x.split_at_mut(index);
    // split second half in [value, ...rest]
    let (val, trailing) = trailing.split_first_mut().unwrap();
    (val, leading, trailing)
}

Using:

let mut v = vec![1, 2, 5, 7, 8, 9];

assert_eq!(
    split_at_rest_mut(&mut v, 2),
    (&mut 5, &mut [1, 2][..], &mut [7, 8, 9][..]),
);

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading