I'm doing Rust Koans and am stuck on a this question:
#[test]
fn for_loops_two() {
let words: [&'static str; 3] = ["I", "love", "Rust"];
let space: &str = " ";
let mut sentence: String = String::new();
for word in words.iter() {
// __
}
println!("{:?}", sentence);
assert!(sentence == "I love Rust".to_string());
}
I know I need to concatenate the string but this will fail:
#[test]
fn for_loops_two() {
let words: [&'static str; 3] = ["I", "love", "Rust"];
let mut sentence: String = String::new();
for word in words.iter() {
sentence.push_str(word);
}
println!("{:?}", sentence); // "ILoveRust"
assert!(sentence == "I love Rust".to_string());
}
I can add a space after each iteration:
#[test]
fn for_loops_two() {
let words: [&'static str; 3] = ["I", "love", "Rust"];
let space: &str = " ";
let mut sentence: String = String::new();
for word in words.iter() {
sentence.push_str(word);
sentence.push_str(space);
}
println!("{:?}", sentence); // "I Love Rust "
assert!(sentence == "I love Rust".to_string());
}
This will also fail because the final iteration will add a space.
I guess I could write a conditional if we are on the last iteration, but I'm struggling to get the syntax correct. Moreover, I feel like there is a much better solution for all of this and I just can't figure out syntax.
How can I make the assertion above pass with a conditional in the loop to not add the space on the last iteration?
You can use slice::join
:
#[test]
fn for_loops_two() {
let words: [&'static str; 3] = ["I", "love", "Rust"];
let sentence = words.join(" ");
assert!(sentence == "I love Rust".to_string());
}
A note on the linked SliceConcatExt
trait: it's listed as unstable on the docs, but the methods are stable - the above compiles just fine under the current stable edition of Rust.
If you'd rather stick to the constraints of the koan and use a for-loop, you can either use an if
as you suggest (figuring out whether you're at the end using enumerate
), or pop
the last space from the end of the string:
#[test]
fn for_loops_two_with_len_check() {
let words: [&'static str; 3] = ["I", "love", "Rust"];
const SPACE: char = ' ';
let number_of_words = words.len();
let mut sentence = String::new();
for (i, word) in words.iter().enumerate() {
sentence.push_str(word);
if i < number_of_words-1 {
sentence.push(SPACE);
}
}
assert!(sentence == "I love Rust".to_string());
}
#[test]
fn for_loops_two_with_pop() {
let words: [&'static str; 3] = ["I", "love", "Rust"];
const SPACE: char = ' ';
let mut sentence = String::new();
for word in words.iter() {
sentence.push_str(word);
sentence.push(SPACE);
}
let _ = sentence.pop();
assert!(sentence == "I love Rust".to_string());
}