是否有保留插入顺序的集类型?

时间:2016-05-31 15:45:58

标签: rust

是否有一种类型可以保留广告订单(想想Vec)但只跟踪唯一值(想想HashSet)?我想避免使用Vec,因为我首先需要在插入之前检查其中是否存在值。

3 个答案:

答案 0 :(得分:4)

linked_hash_set crate现已推出。它基于 linked-hash-map crate尽可能地镜像std HashSet API。

extern crate linked_hash_set;
use linked_hash_set::LinkedHashSet;

let mut set = LinkedHashSet::new();
set.insert(234);
set.insert(123);
set.insert(345);
set.insert(123);

assert_eq!(set.into_iter().collect::<Vec<_>>(), vec![234, 345, 123]);

答案 1 :(得分:3)

linked-hash-map包提供了一个包含键值插入顺序的哈希映射。我们可以使用()为这个哈希映射创建一个集合包装器作为值(std::collections::HashSet以这种方式实现):

extern crate linked_hash_map;

use linked_hash_map::*;
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hash};
use std::borrow::Borrow;

fn main() {
    let mut s = LinkedHashSet::new();
    s.insert(5);
    s.insert(3);
    s.insert(7);
    s.insert(1);
    assert_eq!(vec![5, 3, 7, 1], s.iter().cloned().collect::<Vec<_>>());
    s.remove(&7);
    assert_eq!(vec![5, 3, 1], s.iter().cloned().collect::<Vec<_>>());
    s.remove(&5);
    assert_eq!(vec![3, 1], s.iter().cloned().collect::<Vec<_>>());
}

pub struct LinkedHashSet<K, S = RandomState>(LinkedHashMap<K, (), S>);

impl<K: Hash + Eq> LinkedHashSet<K> {
    pub fn new() -> Self {
        LinkedHashSet(LinkedHashMap::new())
    }
}

impl<K: Hash + Eq, S: BuildHasher> LinkedHashSet<K, S> {
    pub fn insert(&mut self, k: K) -> Option<()> {
        self.0.insert(k, ())
    }

    pub fn contains<Q: ?Sized>(&self, k: &Q) -> bool
        where K: Borrow<Q>,
              Q: Eq + Hash
    {
        self.0.contains_key(k)
    }

    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<()>
        where K: Borrow<Q>,
              Q: Eq + Hash
    {
        self.0.remove(k)
    }

    pub fn iter(&self) -> Keys<K, ()> {
        self.0.keys()
    }
}

您可以实施其他方法。请参阅LinkedHashMap docs

答案 2 :(得分:0)

RiteLinked 在 Rust 中提供了 LinkedHashMap 和 LinkedHashSet 的更多最新版本。您可以轻松地在 std 或 no_std 环境中使用它。您可以使用它代替linked-hash-map 和linked_hash_set。