1

I have a vec: vec![1, 2, 3, 4]. I want to know how to:

  • Iterate its prefixes from shortest to longest:

    &[], &[1], &[1, 2], &[1, 2, 3], &[1, 2, 3, 4]

  • Iterate its prefixes from longest to shortest:

    &[1, 2, 3, 4], &[1, 2, 3], &[1, 2], &[1], &[]

  • Iterate its suffixes from shortest to longest:

    &[], &[4], &[3, 4], &[2, 3, 4], &[1, 2, 3, 4]

  • Iterate its suffixes from longest to shortest:

    &[1, 2, 3, 4], &[2, 3, 4], &[3, 4], &[4], &[],

1 Answers1

2

See also: How to iterate prefixes and suffixes of str or String in rust?

  • What works for a &[T] (i.e. a slice) will also work for &Vec<T> due to Deref coercion

  • To construct a range of indexes from 0 to slice.len() inclusive: 0..=slice.len()

  • std::ops::Range implements both Iterator and DoubleEndedIterator. This allows you to use the rev() method:

    (0..=slice.len()).rev()

  • To get a prefix of a given length: &slice[..len]

  • To get a suffix without the first cut items: &slice[cut..]

Putting it all together

To iterate from shortest to longest:

pub fn prefixes_asc<T>(slice: &[T]) -> impl Iterator<Item = &[T]> + DoubleEndedIterator {
    (0..=slice.len()).map(move |len| &slice[..len])
}

pub fn suffixes_asc<T>(slice: &[T]) -> impl Iterator<Item = &[T]> + DoubleEndedIterator {
    (0..=slice.len()).rev().map(move |cut| &slice[cut..])
}

To reverse just use .rev():

pub fn prefixes_desc<T>(slice: &[T]) -> impl Iterator<Item = &[T]> + DoubleEndedIterator {
    prefixes_asc(slice).rev()
}

pub fn suffixes_desc<T>(slice: &[T]) -> impl Iterator<Item = &[T]> + DoubleEndedIterator {
    suffixes_asc(slice).rev()
}

tests

  • 2
    You could also return `impl Iterator + DoubleEndedIterator` from the two "ascending" functions and call `.rev()` on the result in their respective "descending" counterparts to avoid duplication (at this point, having the "desc" versions doesn't make a lot of sense anymore, since callers can also call `.rev`) – Niklas Mohrin Aug 18 '21 at 18:51