How to own a vec of string references?

How can I get a String joined from references of Strings that I cannot move since these references get used elsewhere?

let features: Vec<&String> 
let my_str: String = features.iter().copied().into_iter().collect::<Vec<String>>().join(",");

value of type Vec<std::string::String> cannot be built from `std::iter::Iterator<Item=&std::string::String>

I know I can solve this by map(|f| format!("{f}")) before collecting, but that seems overkill.

You can clone each string by inserting .cloned() after .copied(). But that's unnecessary: you can just convert to a vector of &str and join those. The .into_iter() is also unnecessary.

See e.g.: Playground

2 Likes

I think you really want

features.iter().map(|s| s.as_str()).intersperse(",").collect()

but that's going to be noisy or unergonomic if you're not on nightly.

Edit: See :point_down:

Or features.iter().join(",")?

7 Likes

@steffahn sadly no join method is found in that case:

method not found in std::slice::Iter<'_, &std::string::String>

This however does work, though probably not efficient?:

features.iter().map(|s| s.to_string()).collect();

That's not the standard method, you have to use itertools::Itertools.

noice!

And I guess this takes the cake as most performance as well as explained here:

Often, the Rust optimiser will be able to figure out that a clone can be replaced with a faster copy. However, this isn't guaranteed, so use copied() where you can, to make sure you end up with the fastest binary.

https://stackoverflow.com/a/58413740/1080804