[SOLVED] Splitting a rust string into a Vec of its substrings with contiguous identical characters

Issue

I have a string or a &str of ascii characters and i want to separate it into a Vec of all substrings with contiguous identical chars (e.g. "aabbca" would become ["aa","bb","c","a"]).

I could build a function that iterates over the individual characters and gradually builds a Vec of strings, but I have the feeling that I’d be reinventing the wheel.
Is there a more idiomatic way to achieve this?

Here’s my intuitive (and current) solution, implemented for &str:

fn split_cont_chars(source:&str) -> Vec<String> {
    let mut answer: Vec<String> = Vec::new();

    let mut head_char = source.chars().next().unwrap();
    let mut counter: usize = 1;

    for c in source.chars().skip(1) {
        if c == head_char {
            counter += 1;
        }
        else {
            answer.push(head_char.to_string().repeat(counter));
            head_char = c;
            counter = 1;
        }
    }
    answer.push(head_char.to_string().repeat(counter));

    answer 
}

This works as intended, but is much more verbose than the average rust code that tackles iterative problems like these.

Solution

There doesn’t seem to be a more functional translations of the original solutions, but there is a more idiomatic one:

struct LetterSequence {
char_type: char,
len: usize}

impl LetterSequence{
    fn new(a:char,b:usize) -> Self {
        LetterSequence{char_type:a,len:b}
    }
    fn to_string(&self) -> String {
        self.char_type.to_string().repeat(self.len)
    }
}

fn split_char_struct(source:&str) -> Vec<LetterSequence> {
    let mut answer: Vec<LetterSequence> = Vec::new();

    let mut seq_count: usize = 1;
    let mut head_char: char = source.chars().next().unwrap();

    for c in source.chars().skip(1) {
        if c == head_char {
            seq_count += 1;
        }
        else {
            answer.push(LetterSequence::new(head_char,seq_count));
            head_char = c;
            seq_count = 1;
        }
    }
    answer.push(LetterSequence::new(head_char,seq_count));

answer}

With the help of the LetterSequence struct, we avoid having to maintain potentially as many mutable strings as the total length of the starting &str

Answered By – none none

Answer Checked By – Gilberto Lyons (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *