迭代枚举中的不同集合

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

我有一个有两个变体的枚举。这些变体之一包含 Vec,另一个包含 BTreeMap。我希望能够迭代这两个包含。实际上,我喜欢“按摩”Vec,使其表现得像 BTreeMap,其中值固定为 1。设置如下:

pub struct Sketch {
    pub name: String,
    pub hashes: Vec<u64>,
}

pub struct WeightedSketch {
    pub name: String,
    pub hashes: BTreeMap<u64, u32>,
}

pub enum SketchType {
    Unweighted(Sketch),
    Weighted(WeightedSketch),
}

impl SketchType {
    pub fn hashes(&self) -> Iter<u64, u32> {
        match self {
            SketchType::Weighted(sketch) => sketch.hashes.iter(),
            SketchType::Unweighted(sketch) => sketch.hashes.iter().map(|hash| (*hash, 1 as u32)).collect::<BTreeMap<u64, u32>>().iter(), 
        }
    }
}

这可以编译,但似乎不是正确的方法。作为一个简单的示例,我希望能够执行以下操作,无论 SketchType 的变体如何:

fn do_work(sketch: &SketchType) -> u64 {
    sketch.values().map(|v| *v as u64).sum()
}

枚举是正确的方法吗?我是否需要以某种方式实现 SketchType 的迭代器特征?

谢谢, 多诺万

rust iterator
1个回答
0
投票

这是您正在寻找的东西吗?

use std::collections::BTreeMap;
use itertools::{Itertools, Either}; // 0.11.0

pub struct Sketch {
    pub name: String,
    pub hashes: Vec<u64>,
}

pub struct WeightedSketch {
    pub name: String,
    pub hashes: BTreeMap<u32, u64>,
}

pub enum SketchType {
    Unweighted(Sketch),
    Weighted(WeightedSketch),
}


impl SketchType {
    /// An iterator through the hash values.
    fn values(&self) -> impl Iterator<Item=u64> + '_ {
        // To reconcile the fact that each branch returns a different type of
        // iterator, we make use of `itertools::Either`, which is designed
        // exactly for that.
        match *self {
            SketchType::Unweighted(ref sketch) => 
                Either::Left(sketch.hashes.iter().cloned()),
            SketchType::Weighted(ref sketch) =>
                Either::Right(sketch.hashes.values().cloned())
        }
    }

    /// Look, `do_work` works!
    fn do_work(&self) -> u64 {
        self.values().sum()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.