This is not possible with Dictionary<TKey, TValue>
as it presents it's values in an unordered fashion when enumerated. There is SortedDictionary<TKey, TValue>
which provides ordering but it does so by using an IComparer<TKey>
against the key value directly. Here you want the key to be a String
and have ordering based on an int
. That is not possible with either of these types.
I think you'll need to implement a new type with these very specific semantics in them. For example.
class OrderedMap<TKey, TValue> {
private readonly Dictionary<TKey, TValue> _map = new Dictionary<TKey, TValue>();
private readonly List<TKey> _list = new List<TKey>();
public void Add(TKey key, TValue value) {
if (!_map.ContainsKey(key)) {
_list.Add(key);
}
_map[key] = value;
}
public void Add(TKey key, TValue value, int index) {
if (_map.ContainsKey(key)) {
_list.Remove(key);
}
_map[key] = value;
_list.Insert(index, key);
}
public TValue GetValue(TKey key) {
return _map[key];
}
public IEnumerabe<KeyValuePair<TKey, TValue>> GetItems() {
foreach (var key in _list) {
var value = _map[key];
yield return new KeyValuePair<TKey, TValue>(key, value);
}
}
}
Note this does come with some non-trivial performance differences over a traditional Dictionary<TKey, TValue>
. For example Add
and Remove
are slower.