减少布尔迭代器

Reduce boolean Iterator

如何使用 && 运算符减少布尔值的 Iterator?这是一个例子(只是相关部分):

let row: Vec<(u32, bool)> = vec![(12, true), (13, false), (15, true)];

row.iter()
    .map(|it| {
        let (_, marked) = it;
        marked
    })
    .reduce(|acc, mk | acc && mk);

编译器建议先解引用acc,然后解引用mk,最后借用整个表达式。这是一个非常简单的操作,但我找不到 Rustacean 的方法来完成它。

在尝试之后,我找到的最佳解决方案是取消引用先前映射中返回的值,因此不是返回对布尔值 returns 的引用,而是一个拥有的副本。这是修改后的问题代码:

let row: Vec<(u32, bool)> = vec![(12, true), (13, false), (15, true)];

row.iter()
    .map(|it| {
        let (_, marked) = it;
        *marked // Dereference here
    })
    .reduce(|acc, mk | acc && mk);

这是使用 fold 指定初始值的替代解决方案:

let val: bool = row.iter()
    .map(|it| {
        let (_, marked) = it;
        marked
    })
    .fold(true, |acc, mk| acc && *mk);

acc && mk 不起作用的原因是因为您在 &bool 上有一个迭代器,但您想要一个 bool*acc && *mk 不起作用,因为累加器的类型是 bool,因此您需要 acc && *mk。但是,您不能再使用 reduce,因为累加器和值不是同一类型(bool&bool),因此需要 fold.

还要注意 foldmap 可以组合:

let val: bool = row.iter()
    .fold(true, |acc, (_, mk)| acc && *mk);

因为有三种常用方法可以从集合中创建迭代器;

iter(), which iterates over &T.
iter_mut(), which iterates over &mut T.
into_iter(), which iterates over T.

你的代码使用了iter(),所以迭代是&类型,所以需要使用&来取值

也许你可以这样做:

    let row: Vec<(u32, bool)> = vec![(12, true), (13, false), (15, true)];

    let op = row.iter()
        .map(|&it| {
            let (_, marked) = it;
            marked // No dereference is required
        })
        .reduce(|acc, mk| acc && mk);
    println!("{:?}",op);

    let row: Vec<(u32, bool)> = vec![(12, true), (13, false), (15, true)];

    let op = row.into_iter()
        .map(|it| {
            let (_, marked) = it;
            marked // No dereference is required
        })
        .reduce(|acc, mk| acc && mk);
    println!("{:?}",op);

我认为最干净的在下面。使用这个 reference pattern;你也可以解构 元组内联,而 fold 有点像 reduce,除了你不会被限制为 Option<Self::Item> 作为 return 类型,并且必须提供一个初始值,等等

let result = row
    .iter()
    .map(|(_, marked)| marked)
    .fold(true, |acc, &mk| acc && mk);

result 将是 bool.

类型