是否有一个Rust函数可以返回迭代器的所有最大值?

7cwmlq89  于 2023-04-21  发布在  其他
关注(0)|答案(2)|浏览(111)

我有一个特定的用例,我需要从Iterator<Item = (i8, f64)>中选择最大元素。如果迭代器中有多个最大元素,我想随机选择一个均匀分布的最大元素。
我尝试了max_by函数的迭代器,但它不工作,因为我需要它,因为它总是返回最后一个元素,如果有多个最大的元素。这里的例子:

fn main() {
    let v = [(-1i8, 0.4f64), (0, 0.2), (1, 0.4)];
    let max = v.into_iter().max_by(|(_, r), (_, s)| r.total_cmp(s)).unwrap(); //always returns (1, 0.4)
    println!("{:?}", max);
}

playground
我需要一个函数返回另一个迭代器的最大元素。然后我可以选择一个随机元素从该迭代器。

mspsb9vt

mspsb9vt1#

在std中没有,但在itertools中有:

iter.max_set();
56lgkhnf

56lgkhnf2#

你可以让你的比较函数在被比较的项相等时随机返回LessGreater,并使用适当的权重来获得均匀的采样:

use rand::{ self, Rng };
use std::cmp::Ordering;

let mut rng = rand::thread_rng();
let mut count = 0;
let max = v.into_iter().max_by(move |(_, r), (_, s)| {
    match r.total_cmp(s) {
        Ordering::Equal => {
            count = count + 1;
            if rng.gen_range (0..=count) == 0 {
                Ordering::Less
            } else {
                Ordering::Greater
            }
        },
        Ordering::Less => {
            count = 0;
            Ordering::Less
        },
        Ordering::Greater => Ordering::Greater,
    }
}).unwrap();

Playground
但是请注意,这取决于Iter::max_by的实现(特别是它将参数传递给比较闭包的顺序),因此您可能需要自己重写它(例如使用Iter::foldIter::reduce)以确保顺序。

相关问题