I'm doing the second level of rustlings for the iterator chapter.
I found the following solution for step 3, and now I would like to chain map and flat_map.
// Step 3.
// Apply the `capitalize_first` function again to a slice of string slices.
// Return a single string.
// ["hello", " ", "world"] -> "Hello World"
pub fn capitalize_words_string(words: &[&str]) -> String {
let capitalized: Vec<String> = words.iter().map(|word| capitalize_first(&word)).collect();
capitalized.iter().flat_map(|s| s.chars()).collect()
}
However, with this naive approach...
words.iter().map(|w| capitalize_first(w)).flat_map(|s| s.char_indices()).collect()
I receive these compiler errors, which I don't understand:
36 | words.iter().map(|w| capitalize_first(w)).flat_map(|s| s.char_indices()).collect()
| ^^^^^^^ value of type `String` cannot be built from `std::iter::Iterator<Item=(usize, char)>`
36 | words.iter().map(|w| capitalize_first(w)).flat_map(|s| s.char_indices()).collect()
| ----- ------ ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Iterator::Item` changed to `(usize, char)` here
| | | |
| | | `Iterator::Item` changed to `String` here
| | `Iterator::Item` is `&&str` here
| this expression has type `&[&str]`
Do you really need to use flat_map
specifically? If not, it would be done like this:
fn capitalize_words_strings(words: &[&str]) -> String {
words.iter()
.map(|word| capitalize_first(word))
.collect()
}
If you really need to use flat_map
, you can just add a "noop" flat_map
by doing std::iter::once()
.
fn capitalize_words_strings(words: &[&str]) -> String {
words.iter()
.map(|word| capitalize_first(word))
.flat_map(|word| std::iter::once(word))
.collect()
}