Rust 从特定索引处的迭代器收集项

Rust 从特定索引处的迭代器收集项,rust,Rust,我想知道是否可以在迭代器上使用.collect来获取特定索引处的项。例如,如果我以字符串开头,我通常会: let line = "Some line of text for example"; let l = line.split(" "); let lvec: Vec<&str> = l.collect(); let text = &lvec[3]; 迭代器上有一个第n个函数可以执行以下操作: let text = line.split(" ").nth(3).u

我想知道是否可以在迭代器上使用.collect来获取特定索引处的项。例如,如果我以字符串开头,我通常会:

let line = "Some line of text for example";
let l = line.split(" ");
let lvec: Vec<&str> = l.collect();
let text = &lvec[3];
迭代器上有一个第n个函数可以执行以下操作:

let text = line.split(" ").nth(3).unwrap();
没有;不过,您可以使用take和next:

注意,这会导致文本成为一个选项,因为不能保证序列实际上至少有四个元素


附录:使用第n个元素显然更短,尽管我更愿意明确地说,访问迭代器的第n个元素必然会消耗它之前的所有元素。

不,不是;但是,您可以在收集之前轻松地进行过滤,这在实践中达到了相同的效果

如果希望按索引进行筛选,则需要在中添加索引,然后将其剥离:

枚举以将索引添加到元素 基于此索引进行筛选 映射以从元素中剥离索引 或在代码中:

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);
}
如果您可以有一个任意谓词,但只希望第一个匹配的元素,那么收集到一个Vec中是低效的:它将消耗整个迭代器,而不是惰性,并可能分配大量根本不需要的内存

因此,最好使用迭代器的下一个方法简单地请求第一个元素,该方法在此处返回一个选项:


如果你想按索引选择部分结果,你也可以在收集之前使用skip和take,但我想你已经有足够多的选择了。

对于任何可能感兴趣的人,你可以用迭代器做很多很酷的事情,谢谢Matthieu M,例如,要根据索引从字符串中获取多个“单词”,您可以使用filter和logical or | | |一起测试多个索引

let line=fcc2cmcmacxx:4:1105:10758:14389 81 chrM 1 32 10S90M=16151 16062 让字:Vec=line.split 列举 .filter | i,124; i==1 | i==3 | i==6 .map | | e | e 收集
谢谢,这也会返回选项吗?当然,这就是展开的目的。基本上是fn unwrapx:Option{if let Somev=x{v}else{panic!Meh}。关于你的附录,我明白你的意思。然而,rust无论如何都是非常明确的:如果您将它写在一行中,那么无论如何都可以,因为您不会在其他任何地方使用部分消耗的拆分。如果您想要分割分割并获得第4项,编译器将强制您编写let mut l=line.split以便能够使用第n项。谢谢,这里有很多内容,但非常有用。您提到收集到Vec中是低效的。您是否能够评论多次执行line.split.enumerate.filter.map.unwrap以从字符串中获取不同项目与将整个内容收集到Vec中,然后使用向量索引检索项目的速度。例如,根据经验法则,如果需要访问1/4的项目,我应该选择哪种方法?@kezzos:我提到将所有内容收集到一个向量中是低效的,我还给出了原因:迭代到最后,当你不关心最后的部分时,并分配内存。如果您需要收集1/4的片段,那么我不会担心内存分配,但是您仍然可以通过使用take缩短迭代来获得收益。还可以将过滤和映射步骤结合起来。
let line = "Some line of text for example";
let l = line.split(" ");
let text = l.skip(3).next();
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);
}
fn main() {
    let line = "Some line of text for example";
    let text = line.split(" ").nth(3).unwrap();
    println!("{}", text);
}
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);
}