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

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

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

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

1 лайк

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

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

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

4 лайка

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

по-моему на chunks стоит обратить внимание:

use std::iter::FromIterator;

fn main() {
    let a = vec![1, 1, 1, 2, 5, 1, 2, 3, 1, 1, 5, 2, 3];
    
    // Borrowed
    let b: Vec<Vec<&i32>> = a
        .as_slice()
        .chunks(5)
        .map(|chunk| Vec::from_iter(chunk.iter()))
        .collect();
        
    println!("{:?}", b);

    // Own
    let c: Vec<Vec<i32>> = a
        .as_slice()
        .chunks(5)
        .map(|chunk| Vec::from_iter(chunk.iter().cloned()))
        .collect();

    println!("{:?}", c);
}

Playground

Не, chunks просто порежет на срезы по пять элементов, а @deepred хотел срезы от одного значения 5 до следующего. Т.е. они каких угодно размеров могут быть.