Cоздать векторы из вектора


#1

Привет всем! У меня возник такой вопрос, как создать вектора из одного вектора, вектор может быть таким: vec![1,1,1,2,5,1,2,3,1,1,5,2,3] и мне нужно сделать так что бы числа от первой пятерки до следующей пятерки были помещены в отдельный вектор, как такое можно сделать?


#2

Тебе нужно один новый вектор создать от первой пятерки до следующей? Мне в голову приходит несколько неуклюжий способ, где надо сначала найти их индексы, потом взять срез, потом преобразовать срез в вектор:

fn main() {
    let v1 = vec![1, 1, 1, 2, 5, 1, 2, 3, 1, 1, 5, 2, 3];
    println!("v1 = {:?}", v1);
    let mut five_indices = v1
        .iter()
        .enumerate()
        .filter_map(|(pos, &value)| if value == 5 { Some(pos) } else { None });
    let index_0 = five_indices.next().unwrap();
    let index_1 = five_indices.next().unwrap();
    let v2 = v1[index_0 + 1..index_1].to_vec();
    println!("v2 = {:?}", v2);
}

вывод:

v1 = [1, 1, 1, 2, 5, 1, 2, 3, 1, 1, 5, 2, 3]
v2 = [1, 2, 3, 1, 1]

Playground


#3

А что делать если этих пятерок может быть не одна, а больше?


#4

Тогда могу предложить магию итераторов.

fn split_on_5(s: &[u32]) -> Vec<Vec<u32>> {
    s.split(|&n| n == 5).map(|slice| slice.to_vec()).collect()
}

fn main() {
    assert_eq!(split_on_5(&[]), vec![vec![]]);
    assert_eq!(split_on_5(&[1]), vec![vec![1]]);
    assert_eq!(split_on_5(&[5]), vec![vec![], vec![]]);
    assert_eq!(split_on_5(&[1, 5, 2, 3, 5, 4]), vec![vec![1], vec![2, 3], vec![4]]);
}

Playground


UPD: Кстати, можно и первый вариант через split сделать было, а не насиловать индексы элементов.

Все то месиво, что я в первом ответе написал, можно заменить на одну строчку:

fn main() {
    let v1 = vec![1, 1, 1, 2, 5, 1, 2, 3, 1, 1, 5, 2, 3];
    println!("v1 = {:?}", v1);
    let v2 = v1.split(|&n| n == 5).nth(1).unwrap().to_vec(); // магия
    println!("v2 = {:?}", v2);
}

Playground


#5

Спасибо огромное за помощь!