从 Vec<Enum> 中找到最大值 - 使用reduce()?

问题描述 投票:0回答:1

我确信有更好的方法来做到这一点,但我不知道如何在reduce()期间从Enum中提取结构。假设所有枚举在向量中都是相同的(但如果这也不成立,则问题解决方案需要处理)。

最简单的例子:

#[derive(Debug)]
struct Data {
    d: u64,
}

#[derive(Debug)]
enum DataEnum {
    First(Data),
    Second,
}

fn main() {
    let v = vec![DataEnum::First(Data{d: 10}), DataEnum::First(Data{d: 5}), DataEnum::First(Data{d: 15}), DataEnum::First(Data{d: 13})];


    let mut vi = v.iter();
    let mut current = vi.next().unwrap();
    let mut max: u64;

    match current {
        DataEnum::First(data) => max = data.d,
        _ => panic!("dont know what to do with {:?}", current),
    }

    for next in vi {
        match next {
            DataEnum::First(data) => if max < data.d {
                current = next;
                max = data.d;
            },
            _ => panic!("dont know what to do with {:?}", next),
        }
    }

    println!("found max: {:?}", current);
}

有没有更好的方法通过折叠或减少来做到这一点?

我遇到的reduce()问题是我不知道如何正确处理闭包内的“匹配”部分(以提取和比较data.d)。

rust enums reduce
1个回答
0
投票

您当然可以在此类代码中使用

reduce()
。我们首先创建一个实用函数,用于检索与比较相关的数据,我们称之为
key
:

fn key(e: &DataEnum) -> u64 {
    match e {
        DataEnum::First(data) => data.d,
        _ => panic!("dont know what to do with {:?}", e),
    }
}

该函数返回

u64
,但它可以返回一个元组或类似的(这是您用来正确支持集合中的异构枚举的)。有了这个功能,你就可以像这样使用
reduce

let max = v
    .iter()
    .reduce(|max, e| if key(e) > key(max) { e } else { max })
    .unwrap();

println!("found max: {:?}", max);

游乐场

然而,Rust 已经提供了一个迭代器方法,通过应用一个键来确定其最大值,方便地称为

max_by_key
,所以你可以使用它:

let max = v.iter().max_by_key(|e| key(e)).unwrap();

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.