Rust &;str
将Rust &;str,rust,iterator,Rust,Iterator,将迭代器转换为字符串,并穿插一些常量字符串(例如“\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"); s=it .
迭代器
转换为字符串
,并穿插一些常量字符串(例如“\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");
s=it
.map(|&x | x)
收集::()
.加入(“\n”);
但是,这不必要地为
Vec
分配内存。有更直接的方法吗?在rust文档中有相关的示例:
let words=[“alpha”,“beta”,“gamma”];
//chars()返回一个迭代器
让合并:String=words.iter()
.flat_映射(|s | s.chars())
.收集();
断言!(合并为“Alphabetagama”);
您还可以使用Extend
trait:
fn f>(数据:I)->字符串{
让mut ret=String::new();
ret.extend(数据);
ret
}
您可以通过使用迭代器的函数轻松完成:
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);
}
fn main(){
设xs=vec![“第一”、“第二”、“第三”];
让它=xs.into_iter();
//让s=it.collect::().join(“\n”);
让s=it.fold(String::new(),|a,b | a+b+“\n”);
设s=s.trim_end();
println!(“{:?}”,s);
}
编辑:在塞巴斯蒂安·雷德尔(Sebastian Redl)的评论之后,我检查了折叠使用的性能成本,并在操场上创建了一个
您可以看到,对于许多迭代方法,fold
的使用要花费更多的时间
但未检查分配的内存使用情况。您可以使用itertools板条箱进行检查。我在示例中使用了helper,它几乎是迭代器的连接等价物
将&str
项转换为&str
项时需要cloned()
,它不执行任何分配。当rust@1.36
获得稳定的发行版
使用itertools::itertools;//0.8.0
fn main(){
让单词=[“alpha”,“beta”,“gamma”];
让合并:String=words.iter().cloned().Interspose(“,”).collect();
assert_eq!(合并为“alpha、beta、gamma”);
}
抱歉-我最初的回答删除了迭代器,但你的问题是如何加入迭代器而不是分配额外的向量。@SimonWhitehead无需担心;我想知道我是否应该说得更清楚。看起来像是
itertools
板条箱注意到,根据迭代器的确切特征,收集到一个切片向量,然后进行连接实际上可能比使用Websterix的方法或itertools
更快,因为SliceConcatExt::join
可以提前计算整个字符串所需的大小,因此在累积期间绝对不需要重新分配;而其他方法可能必须重新分配字符串。您应该明确地进行基准测试。@chpio它必须进行分配,但如果迭代器给出了一个良好的大小提示,则不能重新分配。这个答案不会再现OP的需要。OP询问是否穿插了一些常量字符串(例如“\n”)?。由于字符串已经实现了Extend
,因此在没有flat\u map
的情况下,这也应该可以工作。之所以速度慢,是因为您在每次迭代中使用+创建两个新字符串。如果使用单个字符串(),它的工作效果会比collect和join()更好。添加了black_box
,并分别为每个测试创建vec(因为缓存变暖)()。由于延迟/持续时间的巨大差异,Playerd不太适合基准测试,但折叠变体似乎稍微慢一点(多次运行)。使用black_-box(xs).iter().copied()
现在需要两倍于collect+join-over-fold的时间(黑色_-box(xs)没有关系,xs
是一样的)。我猜他们优化了一些东西,比如vec![“嘿”;100_000]。放入iter()。收集
只返回原始vec?!对