减少布尔迭代器
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
.
还要注意 fold
和 map
可以组合:
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
.
类型
如何使用 &&
运算符减少布尔值的 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
.
还要注意 fold
和 map
可以组合:
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
.