2012-01-25 15 views
7

我想要一個ID索引列表,由我的類中的特殊屬性排序。SortedList由非關鍵字索引

排序列表,沒有做這個,因爲它迫使我在關鍵排序...

比方說我的課是

class example{ 
int Id; 
int Order 
} 

有沒有被索引像一本字典的任何結構,由其他東西訂購?

,這樣我可以通過ID訪問數據,但在foreach中的數據由順序排序

回答

2

據我所知,沒有Dictionary類型的對象,這將使你的行爲的權利開箱。

如果您只擔心在foreach循環中以特定順序訪問,那麼爲什麼不使用LINQ

SortedList<int, example> sortedList = new SortedList<int, example>(); 
... //populate list 

var sortedByOrder = from kp in sortedList 
        orderby kp.Value.Order 
        select kp; 

foreach (var kp in sortedByOrder) 
{ 
    ... //access will be ordered by example.Order 
} 

是的,你會在性能上支付違約金,但如果它不是一個問題,這是,恕我直言,以得到你想要的最簡單的方法。

+0

被指定爲我只加了一次項目,我用您的解決方案 – RagnaRock

2

AFAIK有作爲標準,將提供基於價值排序提供什麼,但還是提供了O(1)查找像字典。但是寫的東西可以做到這一點很簡單:

public class SortedLookup<TKey, TValue> : IEnumerable<TValue> 
{ 
    private readonly Dictionary<TKey, TValue> _lookup; 
    private readonly IComparer<TValue> _comparer; 

    public SortedLookup(IComparer<TValue> comparer) 
    { 
    _lookup = new Dictionary<TKey, TValue>(); 
    _comparer = comparer; 
    } 

    public TValue this[TKey key] 
    { 
    get { return _lookup[key]; } 
    set { _lookup[key] = value; } 
    } 

    public IEnumerator<TValue> GetEnumerator() 
    { 
    return _lookup.Values.OrderBy(v => v, _comparer).GetEnumerator(); 
    } 

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

如果集合必須在任何時候訂購,那麼由有序集合和字典組成的混合集合可能是一個解決方案。

我的解決方案只實現了ICollection<TValue>,但是您也可能想要實現其他接口或單個方法。

public class SortedKeydCollection<TKey, TOrder, TValue> : ICollection<TValue> 
{ 
    private Dictionary<TKey, TValue> _dict = new Dictionary<TKey, TValue>(); 
    private SortedList<TOrder, TValue> _list = new SortedList<TOrder, TValue>(); 
    Func<TValue, TKey> _keySelector; 
    Func<TValue, TOrder> _orderSelector; 

    public SortedKeydCollection(Func<TValue, TKey> keySelector, Func<TValue, TOrder> orderSelector) 
    { 
     _keySelector = keySelector; 
     _orderSelector = orderSelector; 
    } 

    #region ICollection<TValue> Members 

    public void Add(TValue item) 
    { 
     _dict[_keySelector(item)] = item; 
     _list[_orderSelector(item)] = item; 
    } 

    public void Clear() 
    { 
     _dict.Clear(); 
     _list.Clear(); 
    } 

    public bool Contains(TValue item) 
    { 
     return _dict.ContainsKey(_keySelector(item)); 
    } 

    public void CopyTo(TValue[] array, int arrayIndex) 
    { 
     int i = arrayIndex; 
     foreach (TValue item in _list.Values) { 
      if (i >= array.Length) { 
       break; 
      } 
      array[i++] = item; 
     } 
    } 

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

    public bool IsReadOnly 
    { 
     get 
     { 
      return ((ICollection<KeyValuePair<TOrder, TValue>>)_list).IsReadOnly || 
        ((ICollection<KeyValuePair<TKey, TValue>>)_dict).IsReadOnly; 
     } 
    } 

    public bool Remove(TValue item) 
    { 
     bool res1 = _list.Remove(_orderSelector(item)); 
     bool res2 = _dict.Remove(_keySelector(item)); 
     return res1 && res2; 
    } 

    #endregion 

    #region IEnumerable<TValue> Members 

    public IEnumerator<TValue> GetEnumerator() 
    { 
     return _list.Values.GetEnumerator(); 
    } 

    #endregion 

    #region IEnumerable Members 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return _list.Values.GetEnumerator(); 
    } 

    #endregion 
} 

注意的關鍵和順序選擇在構造函數中

var collection = new SortedKeydCollection<int, int, example>(x => x.Id, x => x.Order);