Join iterator of &str

13,580

Solution 1

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

Solution 2

You can do it by using fold function of the iterator easily:

let s = it.fold(String::new(), |a, b| a + b + "\n");

The Full Code will be like following:

fn main() {
    let xs = vec!["first", "second", "third"];
    let it = xs.into_iter();

    // let s = it.collect::<Vec<&str>>().join("\n");

    let s = it.fold(String::new(), |a, b| a + b + "\n");
    let s = s.trim_end();

    println!("{:?}", s);
}

Playground

EDIT: After the comment of Sebastian Redl I have checked the performance cost of the fold usage and created a benchmark test on playground.

You can see that fold usage takes significantly more time for the many iterative approaches.

Did not check the allocated memory usage though.

Share:
13,580
Mateen Ulhaq
Author by

Mateen Ulhaq

Elen síla lúmenn' omentielvo. Favorite languages: Python, Rust, Kotlin, C++, C#, Haskell Photography

Updated on June 06, 2022

Comments

  • Mateen Ulhaq
    Mateen Ulhaq almost 2 years

    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 joining 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?