将 an 转换Iterator<&str>为 a的规范方法是什么String,穿插一些常量字符串(例如"\n")?
例如,给定:
let xs = vec!["first", "second", "third"];
let it = xs.iter();
Run Code Online (Sandbox Code Playgroud)
有一种方法可以s通过收集到 someIterable并joining 结果来生成字符串:
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)
有了,您不仅itertools拥有:intersperse()join()
use itertools::Itertools;
let s = it.join("\n");
Run Code Online (Sandbox Code Playgroud)
它比intersperse()(它接受任何Display实现类型)更通用,但因此可能会更慢(尽管我没有进行基准测试)。
您可以通过使用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使用许多迭代方法需要花费更多的时间。
虽然没有检查分配的内存使用情况。
小智 -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)
| 归档时间: |
|
| 查看次数: |
8562 次 |
| 最近记录: |