【问题标题】:Return a moving window of elements resulting from an iterator of Vec<u8>返回由 Vec<u8> 的迭代器产生的元素的移动窗口
【发布时间】:2015-06-14 19:18:02
【问题描述】:

我试图弄清楚如何从我首先过滤的向量中返回一个元素窗口,而不将其复制到新向量中。

所以这是一种天真的方法,效果很好,但我认为最终会从第 5 行分配一个我不想做的新向量。

let mut buf  = Vec::new();
file.read_to_end(&mut buf);
// Do some filtering of the read file and create a new vector for subsequent processing
let iter = buf.iter().filter(|&x| *x != 10 && *x != 13);
let clean_buf = Vec::from_iter(iter);
for iter in clean_buf.windows(13) {
    print!("{}",iter.len());
}

我可以使用链()的替代方法?在不复制到新的 Vec 的情况下实现相同的目标

for iter in buf.iter().filter(|&x| *x != 10 && *x != 13) {
    let window =  ???       
}

【问题讨论】:

  • 从描述中不清楚:之后您还需要buf 吗?还是可以修改(read_to_end之后)?
  • 一旦我有了clean_buf,在这个例子中我就不再需要它了

标签: iterator rust


【解决方案1】:

您可以为此使用Vec::retain 而不是filter,这样可以保留您的 Vec:

fn main() {
    let mut buf = vec![
        8, 9, 10, 11, 12, 13, 14,
        8, 9, 10, 11, 12, 13, 14,
        8, 9, 10, 11, 12, 13, 14,
    ];
    println!("{:?}", buf);
    buf.retain(|&x| x != 10 && x != 13);
    println!("{:?}", buf);
    for iter in buf.windows(13) {
        print!("{}, ", iter.len());
    }
    println!("");
}

【讨论】:

  • 啊,我没想到 OP 会允许修改缓冲区!很好的横向思维:-)
【解决方案2】:

我不明白这怎么可能。你说:

我首先过滤的向量中的元素

但是一旦你 filtered 一个向量,你就不再有一个向量 - 你只有一个 IteratorIterators 只有下一项的概念。

为了最有效,您必须创建一个与窗口大小相同的小缓冲区。不幸的是,您是cannot write an iterator that returns a reference to itself,因此您必须将缓冲区传递给假设的Iterator::windows 方法。在这种情况下,您会遇到一个问题,即有一个可变引用(因此您可以填充缓冲区)和一个不可变引用(因此您可以返回一个切片),这不会飞。

我能想到的唯一接近的解决方案是在同一个向量上使用多个迭代器,然后将 zip 放在一起:

fn main() {
    let nums: Vec<u8> = (1..100).collect();

    fn is_even(x: &&u8) -> bool { **x % 2 == 0 }

    let a = nums.iter().filter(is_even);
    let b = nums.iter().filter(is_even).skip(1);
    let c = nums.iter().filter(is_even).skip(2);

    for z in a.zip(b).zip(c).map(|((a, b), c)| (a,b,c)) {
        println!("{:?}", z);
    }  
}

这具有需要多次应用过滤条件的明显缺点,以及嵌套拉链的丑陋(尽管您可以使用itertools 修复后者)。

就我个人而言,我可能只是将collect 改成Vec,就像你已经完成的那样。

【讨论】:

    猜你喜欢
    • 2020-10-28
    • 2016-02-06
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多