Iterator to Vec<String>

Hey there, my problem is that i have a Vec of Strings and do some filtering over them via Iterator. So now I want another Vec with the filtered result inside but I can't figure out how to get it from the iterator.

this is my code so far:

// get max length
let mut max_len = inputArray.iter().fold(0, |acc, item| { if item.len() > acc { item.len() } else { acc } });
let result: Vec<String> = inputArray.iter().filter(|x| x.len() == max_len);

You can use the collect method to turn an iterator into a Vec or other collection:

let result: Vec<String> = inputArray.iter()
    .filter(|x| x.len() == max_len)
    .collect();
1 Like

Yeah i read that but if i just call collect i get this error
error[E0277]: a collection of type std::vec::Vec<std::string::String> cannot be built from an iterator over elements of type &std::string::String
--> file.rs on line 4:80
|
9 | let result: Vec = inputArray.iter().filter(|x| x.len() == max_len).collect();
| ^^^^^^^ a collection of type std::vec::Vec<std::string::String> cannot be built from std::iter::Iterator<Item=&std::string::String>
|
= help: the trait std::iter::FromIterator<&std::string::String> is not implemented for std::vec::Vec<std::string::String>

Oh, right. You have a few choices. If you want to clone the strings from inputArray, you can use the cloned method, which will copy the strings, leaving the originals intact:

inputArray.iter().filter(...).cloned().collect()

If inputArray has type Vec<String>, and you don't need to use it anymore, you can use Vec::into_iter to consume the old vector and move its contents into the new one:

inputArray.into_iter().filter(...).collect()

Or if inputArray is a mutable Vec, then you could filter it in place with the retain method instead of creating a new Vec:

inputArray.retain(|x| x.len() == max_len);
// `inputArray` now contains only the retained elements
2 Likes

thanks :slight_smile:
It works now.