加入&str的迭代器

时间:2019-05-08 03:53:45

标签: rust iterator

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

例如,给定:

let xs = vec!["first", "second", "third"];
let it = xs.iter();

有一种方法可以通过将字符串收集到s中并Iterable来生成字符串join

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

但是,这不必要地为Vec<&str>分配了内存。有更直接的方法吗?

3 个答案:

答案 0 :(得分:2)

您可以使用 itertools 板条箱。在示例中,我使用了documentation帮助器,它几乎等同于 join 迭代器。

需要

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");
}

intersperse

答案 1 :(得分:1)

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

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

完整代码如下:

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

编辑:在塞巴斯蒂安·雷德尔(Sebastian Redl)发表评论后,我检查了折叠使用的性能成本,并在运动场上创建了benchmark test

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

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

答案 2 :(得分:-1)

防锈文档中有相关示例: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");

您还可以使用Extend特征:

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