Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Concatenate a slice of `&str`s into an owned `String`

I am trying to concatenate every element in a slice of &strs (&[&str]) into a single owned String. For example, I want to turn &['Hello', ' world!'] into "Hello world!".

I tried to do this by converting the slice into an iterator, then mapping over the iterator and converting each &str into an owned String, then collect them all into a Vec<String> and running .join(""), but I keep getting a type error.

Here is my code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

fn concat_str(a: &[&str]) -> String {
    a.into_iter().map(|s| s.to_owned()).collect::<Vec<String>>().join("")
}

fn main() {
    let arr = ["Dog", "Cat", "Bird", "Lion"];

    println!("{}", concat_str(&arr[..3])); // should print "DogCatBird"
    println!("{}", concat_str(&arr[2..])); // should print "BirdLion"
    println!("{}", concat_str(&arr[1..3])); // should print "CatBird"
}

And here is the compiler error that I am getting:

error[E0277]: a value of type `Vec<String>` cannot be built from an iterator over elements of type `&str`
    --> code.rs:2:38
     |
2    |     a.into_iter().map(|s| s.to_owned()).collect::<Vec<String>>().join("")
     |                                         ^^^^^^^ value of type `Vec<String>` cannot be built from `std::iter::Iterator<Item=&str>`
     |
     = help: the trait `FromIterator<&str>` is not implemented for `Vec<String>`
note: required by a bound in `collect`
    --> /Users/michaelfm1211/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:1780:19
     |
1780 |     fn collect<B: FromIterator<Self::Item>>(self) -> B
     |                   ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

It says that I cannot collect into a Vec<String> because the iterator is not of a String, but I thought that I had converted it to a String with .map(|s| s.to_owned()).

How can I fix this? I am also new to rust, so it would be very helpful is someone could explain what I did wrong.

>Solution :

into_iter will yield an iterator with Item=&&str. In your map, .to_owned() converts that into a &str, which doesn’t work. There are a few ways to fix that, you could use .copied or .cloned to get a &str:

a.into_iter().copied().map(|s| s.to_owned()).collect::<Vec<String>>().join("")
// or
a.into_iter().cloned().map(|s| s.to_owned()).collect::<Vec<String>>().join("")

Or you could use .to_string() to get a String directly:

a.into_iter().map(|s| s.to_string()).collect::<Vec<String>>().join("")

Note, you can also just collect into a String when you don’t want a separator directly:

a.into_iter().map(|s| s.to_string()).collect::<String>()
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading