What is the canonical method to convert an Iterator<&str>
to a String
, interspersed with some constant string (e.g. "\n"
)?
For instance, given:
let xs = vec!["first", "second", "third"];
let it = xs.iter();
There is a way to produce a string s
by collecting into some Iterable
and join
ing the result:
let s = it
.map(|&x| x)
.collect::<Vec<&str>>()
.join("\n");
However, this unnecessarily allocates memory for a Vec<&str>
. Is there a more direct method?
collect() can take all the values in an Iterator 's stream and stick them into a Vec . And the map method is now generating Result<i32, &str> values, so everything lines up.
Iterators. An iterator helps to iterate over a collection of values such as arrays, vectors, maps, etc. Iterators implement the Iterator trait that is defined in the Rust standard library. The iter() method returns an iterator object of the collection. Values in an iterator object are called items.
You can make your iterator peekable and peek the first item; if it's None , then the iterator is empty. peek doesn't consume the item1, so the next call to next will return it.
You could use the itertools crate for that. I use the intersperse helper in the example, it is pretty much the join equivalent for iterators.
cloned()
is needed to convert &&str
items to &str
items, it is not doing any allocations. It can be eventually replaced by copied()
when [email protected]
gets a stable release.
use itertools::Itertools; // 0.8.0
fn main() {
let words = ["alpha", "beta", "gamma"];
let merged: String = words.iter().cloned().intersperse(", ").collect();
assert_eq!(merged, "alpha, beta, gamma");
}
Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With