【问题标题】:Idiomatic way to count occurrences in a collection of Options计算选项集合中出现次数的惯用方法
【发布时间】:2019-09-21 23:53:15
【问题描述】:

我想计算选项集合中某个值的出现次数。

let v = vec![Some(1), Some(1), Some(3), None];
v.iter()
 .filter(|Some(x)| x == &1)
 .count();

这样做会产生refutable pattern not covered 错误,这是有道理的。

我通过这样做解决了这个问题

v.iter()
 .filter(|x| x.is_some() && x.unwrap() == &1)
 .count()

在 rust 中执行此操作的惯用方法是什么?

【问题讨论】:

  • 你很亲密:.filter(|&x| x == Some(1))
  • 你也想数 None 吗?
  • 对不起,我选择了一个简化的例子。我的 x 是一个结构,我需要将它与 rhs 中的传递值进行比较。喜欢x.is_some() && x.unwrap().value() == id
  • 我不在乎Nones

标签: rust idioms


【解决方案1】:

您可以使用flatten 摆脱None 并解开Some(...) 值。

代码:

let one_count = v.iter().flatten().filter(|x| **x == 1).count();

要计算 None s,您可以简单地使用:

let none_count = v.len() - v.iter().flatten().count();

Playground

为什么 Flatten 适用于 Options ?

来自@E_net4 's comment:由于Option 实现了IntoIterator,它可以表现得像一个空迭代器或具有单个元素的迭代器。

  • Iterator 为空 None
  • IteratorSome(...) 的单个元素

【讨论】:

  • flatten on None 返回什么?
  • @pd176 从迭代器中删除 None 值,Option 迭代器存在这种行为。 (Err 的值与 Result 迭代器相同)
  • @pd176 flatten 在这里工作,因为 Option 可以表现得像具有 0 或 1 个元素的迭代器;它实现了IntoIterator
  • @E_net4 谢谢,这是一个更好的解释,我会尽可能地编辑答案。
猜你喜欢
  • 1970-01-01
  • 2012-12-24
  • 1970-01-01
  • 2013-08-22
  • 2012-08-08
  • 1970-01-01
  • 2017-03-08
  • 2011-07-02
  • 1970-01-01
相关资源
最近更新 更多