Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functional way to split string into offset substrings

Tags:

rust

I'm on rustc 1.0.0-beta (9854143cb 2015-04-02) (built 2015-04-02)

My goal is to split a string of length n into n-k+1 offset substrings of length k. What I mean by that is if you have a string:

ABCDEF

I'm trying to obtain a vector/iterator that contains offset substrings of arbitrary length k. For example, k=3 would yield

ABC
 BCD
  CDE
   DEF

And k=2 would yield:

AB
 BC
  CD
   DE
    EF

Note that the whitespace is only included above to align the substrings to show how they are related. The output vector would only include AB,BC, CD, etc. Also, it's ok to only support ASCII, although I would prefer a safer more generic solution.

As painful as it is to look at, the following procedural code seems to work:

fn offset_slices(s: &str, n: usize) -> Vec<&str> {
    let mut slices: Vec<&str> = Vec::new();
    for (i,_) in s.chars().enumerate() {
        if i > s.len() - n {
            break;
        }
        slices.push(&s[i..(i+n)]);
    }
    slices
}

But it's nasty and I would prefer a more functional solution. I spent a couple hours trying to figure out a way, and learned a lot in the process, but I'm stumped on this one.

Any ideas?

PS - I'm really surprised that the slices.push(&s[i..(i+n)]) above even compiles. Is it just returning pointers to various locations of the input?

like image 534
anderspitman Avatar asked Mar 16 '23 09:03

anderspitman


1 Answers

fn offset_slices(s: &str, n: usize) -> Vec<&str> {
    (0 .. s.len() - n + 1).map(|i| &s[i .. i + n]).collect()
}
like image 106
KOlegA Avatar answered Mar 24 '23 13:03

KOlegA