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)