加入 &str 的迭代器

Mat*_*haq 14 iterator rust

将 an 转换Iterator<&str>为 a的规范方法是什么String,穿插一些常量字符串(例如"\n")?

例如,给定:

let xs = vec!["first", "second", "third"];
let it = xs.iter();
Run Code Online (Sandbox Code Playgroud)

有一种方法可以s通过收集到 someIterablejoining 结果来生成字符串:

let s = it
    .map(|&x| x)
    .collect::<Vec<&str>>()
    .join("\n");
Run Code Online (Sandbox Code Playgroud)

但是,这不必要地为Vec<&str>. 有没有更直接的方法?

chp*_*pio 10

您可以为此使用itertools板条箱。我在示例中使用了intersperse助手,它几乎与迭代器的连接等效。

cloned()需要将&&str项目转换为&str项目,它不进行任何分配。copied()rust@1.36获得稳定版本时,它最终可以被替换。

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");
}
Run Code Online (Sandbox Code Playgroud)

操场


Cha*_*man 8

有了,您不仅itertools拥有:intersperse()join()

use itertools::Itertools;

let s = it.join("\n");
Run Code Online (Sandbox Code Playgroud)

它比intersperse()(它接受任何Display实现类型)更通用,但因此可能会更慢(尽管我没有进行基准测试)。


Web*_*rix 7

您可以通过使用fold迭代器的功能轻松地做到这一点:

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

完整代码如下所示:

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);
}
Run Code Online (Sandbox Code Playgroud)

操场

编辑:在 Sebastian Redl 发表评论后,我检查了折叠使用的性能成本并在操场上创建了一个基准测试

您可以看到,fold使用许多迭代方法需要花费更多的时间。

虽然没有检查分配的内存使用情况

  • 这很慢的原因是因为您在每次迭代中使用 + 创建两个新字符串。如果您使用单个字符串 ([playground](https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=f2740a132f69b5d41d14a3472c98674e)),它可以比收集和加入 ([playground](https: //play.rust-lang.org/?version=stable&amp;mode=release&amp;edition=2018&amp;gist=5fa149bbd78707d7ff4e257d38318361))。 (20认同)

小智 -4

Rust 文档中有相关示例:here

let words = ["alpha", "beta", "gamma"];

// chars() returns an iterator
let merged: String = words.iter()
                          .flat_map(|s| s.chars())
                          .collect();
assert_eq!(merged, "alphabetagamma");
Run Code Online (Sandbox Code Playgroud)

您还可以使用Extend特征:

fn f<'a, I: Iterator<Item=&'a str>>(data: I) -> String {
    let mut ret = String::new();
    ret.extend(data);
    ret
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案没有重现OP的需求。OP正在询问是否散布一些常量字符串(例如“\n”)? (7认同)