Я делаю второй уровень шорохов для главы об итераторе.
Я нашел следующее решение для шага 3, и теперь я хотел бы объединить карты и 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()
}
Однако при таком наивном подходе...
words.iter().map(|w| capitalize_first(w)).flat_map(|s| s.char_indices()).collect()
Я получаю эти ошибки компилятора, которые я не понимаю:
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]`
Также вы можете собрать итератор строк прямо в строку. Не нужно превращать их в персонажей.
@drewtato, да, наверное, я не увидел здесь очевидного -.-
@vallentin, поэтому меня смутило то, что это работало в моем первоначальном решении, где я сначала собирал результат карты, а затем снова превращал его в итератор с iter
, который будет использоваться flat_map
. Но тогда я не был уверен, почему нельзя просто удалить collect
и iter
и объединить строки.
Вам действительно нужно конкретно использовать flat_map
? Если нет, то это будет сделано так:
fn capitalize_words_strings(words: &[&str]) -> String {
words.iter()
.map(|word| capitalize_first(word))
.collect()
}
Если вам действительно нужно использовать flat_map
, вы можете просто добавить «нуп» flat_map
, выполнив 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()
}
Я смущен вашим замешательством. chars() выдаёт
char
s, а char_indices() выдаёт индексированные символы, т.е.(usize, char)
. Это не то же самое. Собиратьchar
можно только вString
. Так что, если вам нужен индекс, вам нужно дополнительно.map(|(i, c)| c)
избавиться от него, прежде чем.collect()
использовать