我想知道是否可以在迭代器上使用.collect()
来获取特定索引处的项目。例如,如果我以字符串开头,我通常会这样做:
let line = "Some line of text for example";
let l = line.split(" ");
let lvec: Vec<&str> = l.collect();
let text = &lvec[3];
但最好的是:
let text: &str = l.collect(index=(3));
答案 0 :(得分:12)
不,不是;但是,在收集之前,您可以轻松过滤,这实际上可以达到同样的效果。
如果您希望按索引进行过滤,则需要添加索引,然后将其删除:
enumerate
(将索引添加到元素中)filter
基于此索引map
从元素或代码:
fn main() {
let line = "Some line of text for example";
let l = line.split(" ")
.enumerate()
.filter(|&(i, _)| i == 3 )
.map(|(_, e)| e);
let lvec: Vec<&str> = l.collect();
let text = &lvec[0];
println!("{}", text);
}
如果您只想获得单个索引(以及元素),那么使用nth
会更容易。它在这里返回Option<&str>
,您需要注意:
fn main() {
let line = "Some line of text for example";
let text = line.split(" ").nth(3).unwrap();
println!("{}", text);
}
如果你可以拥有一个任意谓词,但只希望匹配的第一个元素,那么收集到Vec
是低效的:它将消耗整个迭代器(没有懒惰)并且可能分配大量的内存。根本不需要。
因此,您最好只使用迭代器的next
方法请求第一个元素,该方法在此处返回Option<&str>
:
fn main() {
let line = "Some line of text for example";
let text = line.split(" ")
.enumerate()
.filter(|&(i, _)| i % 7 == 3 )
.map(|(_, e)| e)
.next()
.unwrap();
println!("{}", text);
}
如果你想通过索引选择结果的部分,你也可以在收集之前使用skip
和take
,但我猜你这里有足够的选择已经
答案 1 :(得分:9)
nth
上有一个Iterator
函数执行此操作:
let text = line.split(" ").nth(3).unwrap();
答案 2 :(得分:2)
没有;不过,您可以使用take
和next
:
let line = "Some line of text for example";
let l = line.split(" ");
let text = l.skip(3).next();
请注意,这会导致text
成为Option<&str>
,因为不能保证序列实际至少有至少四个元素。
附录:使用nth
肯定会更短,但我更愿意明确访问 n th 迭代器的元素必须消耗之前的所有元素。
答案 3 :(得分:0)
对于任何可能感兴趣的人,你可以用迭代器做很多很酷的事情(感谢Matthieu M),例如根据索引从字符串中获取多个'words',你可以使用filter
与逻辑或||
一起测试多个索引!
let line = "FCC2CCMACXX:4:1105:10758:14389# 81 chrM 1 32 10S90M = 16151 16062"
let words: Vec<&str> = line.split(" ")
.enumerate()
.filter(|&(i, _)| i==1 || i==3 || i==6 )
.map(|(_, e) | e)
.collect();