任何现有的.Net订购套装?

时间:2014-12-05 08:22:58

标签: c# .net list collections set

我正在寻找.Net类,基本上会:

  • 确保项目中的项目是唯一的(如HashSet)
  • 确保在我们枚举时,我们获得的项目顺序与插入项目相同(如列表)

是否存在可以执行此操作的.Net类?

我知道HashSet(不保证订单),SortedSet(内容上的订单),但它们不匹配我的需要。我没有其他任何需求(例如StackQueue)。

我目前的替代方案是拥有List<>并在添加和删除数据之前使用Contains(...)

2 个答案:

答案 0 :(得分:2)

你是对的。 HashSet不保留插入顺序。

Stackoverflow: HashSet that preserves ordering by achitaka-san 它使用Dictionary查找项目,使用LinkedList保存顺序。所有三个插入,删除和查找工作仍然在O(1)。

public class OrderedSet<T> : ICollection<T>
{
    private readonly IDictionary<T, LinkedListNode<T>> m_Dictionary;
    private readonly LinkedList<T> m_LinkedList;

    public OrderedSet()
        : this(EqualityComparer<T>.Default)
    {
    }

    public OrderedSet(IEqualityComparer<T> comparer)
    {
        m_Dictionary = new Dictionary<T, LinkedListNode<T>>(comparer);
        m_LinkedList = new LinkedList<T>();
    }

    public int Count
    {
        get { return m_Dictionary.Count; }
    }

    public virtual bool IsReadOnly
    {
        get { return m_Dictionary.IsReadOnly; }
    }

    void ICollection<T>.Add(T item)
    {
        Add(item);
    }

    public bool Add(T item)
    {
        if (m_Dictionary.ContainsKey(item)) return false;
        LinkedListNode<T> node = m_LinkedList.AddLast(item);
        m_Dictionary.Add(item, node);
        return true;
    }

    public void Clear()
    {
        m_LinkedList.Clear();
        m_Dictionary.Clear();
    }

    public bool Remove(T item)
    {
        LinkedListNode<T> node;
        bool found = m_Dictionary.TryGetValue(item, out node);
        if (!found) return false;
        m_Dictionary.Remove(item);
        m_LinkedList.Remove(node);
        return true;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return m_LinkedList.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public bool Contains(T item)
    {
        return m_Dictionary.ContainsKey(item);
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        m_LinkedList.CopyTo(array, arrayIndex);
    }
}

另一种实施方式:

@Codeproject: HashSet that Preserves Insertion Order or .NET Implementation of LinkedHashSet

答案 1 :(得分:1)

您可以使用OrderedDictionary,找到文档here

您将使用当前List中的值作为字典中的键,您可以将值保留为随机值。

OrderedDictionary myOrderedDictionary = new OrderedDictionary();
myOrderedDictionary.Add(1, "smth");
myOrderedDictionary.Add(2, "smth");

foreach (DictionaryEntry v in myOrderedDictionary)
{
    int youValue = (int)v.Key;
}

这里唯一的缺点就是这本词典没有使用泛型,你必须自己object投射。