9

Is there an collection in .net that allows the storing KeyValuePair<string, string> that keeps the order of inserting?
OrderedDictionary looked promising, but seems to be rather lacking.
Now I'm looking into IOrderedEnumerable>, but I can't seem to find any implementation except for ISortedDictionary, but that's not what I want. No sorting needs to be done, just the order of inserting is important.

Update
The reason I don't like OrderedDictionary is that it's not generic.

Boris Callens
  • 90,659
  • 85
  • 207
  • 305
  • OrderedDictionary is not sorting the values and you can access the elements by the index. What exactly is lacking ? – Adrian Fâciu Jun 18 '10 at 15:01
  • `OrderedDictionary` is intended for what you're looking for, unfortunately it's not generic. Beyond that, is there anything else missing in it that you're looking for? You'll get better answers if you can clarify what you're looking for (and why built-in classes don't meet your needs). – LBushkin Jun 18 '10 at 15:08
  • I would like to evade all the casting if possible. – Boris Callens Jun 19 '10 at 20:36

5 Answers5

9

Although I am late to the game, .NET Framework 4.5 provides new classes for you. See SortedList<TKey, TValue> or SortedDictionary<TKey, TValue>. If you are wondering which one you should use, the MSDN provides a few good reasons why you might choose one over the other.

The SortedList generic class is an array of key/value pairs with O(log n) retrieval, where n is the number of elements in the dictionary. In this, it is similar to the SortedDictionary generic class. The two classes have similar object models, and both have O(log n) retrieval. Where the two classes differ is in memory use and speed of insertion and removal:

  • SortedList<TKey, TValue> uses less memory than SortedDictionary<TKey, TValue>.
  • SortedDictionary<TKey, TValue> has faster insertion and removal operations for unsorted data, O(log n) as opposed to O(n) for SortedList<TKey, TValue>.
  • If the list is populated all at once from sorted data, SortedList<TKey, TValue> is faster than SortedDictionary<TKey, TValue>.

Another difference between the SortedDictionary<TKey, TValue> and SortedList<TKey, TValue> classes is that SortedList<TKey, TValue> supports efficient indexed retrieval of keys and values through the collections returned by the Keys and Values properties. It is not necessary to regenerate the lists when the properties are accessed, because the lists are just wrappers for the internal arrays of keys and values.

Both links have similar Remarks section (which is where the quote comes from). They also have more information for both classes. I'd recommend reading both sections if you are interested in using one of them.

techvice
  • 1,315
  • 1
  • 12
  • 24
  • 1
    SortedList does not maintain order of insertion which the OP asks for (and which I was looking for). – Brad Patton Aug 14 '18 at 16:38
  • List of KeyValue pair is the best way as compared to OrderedList/OrderedDictionary. This maintains index as per insertion and support Generic type. – Kumar Shishir Oct 07 '20 at 21:54
9

Just use List<KeyValuePair<T,T>>. They are stored in order of insertion. Every time you add to it, the newest one is added to the end of the list.

so

var list = new List<KeyValuePair<String,String>>();

list.Add(new KeyValuePair<String,String>("",""));

If you want to pull them out in order just use:

list.ForEach(x=>...);

or

foreach(var item in list){
...}
depperm
  • 10,606
  • 4
  • 43
  • 67
kemiller2002
  • 113,795
  • 27
  • 197
  • 251
8

OrderedDictionary is what you want if you need both keyed and insertion-sequenced access to items ... it's really just a combination of a hash table and a list. It provides a means to access items in it either by insertion index or by key. It's the only collection in .NET that does this. Sadly, it is not generic.

If OrderedDictionary doesn't meet your needs solely because it is not generic - then you can use the version here that provides a generic equivalent. If there are other reasons why it doesn't work for you, update your post and we can look for a better option.

While you can certainly create your own List<KeyValuePair<string,string>> you will lose the option of searching by key efficiently. Now, you can certainly roll your own implementation of an ordered doctionary that combined list/dict together ... but the post I've linked to already does this.

LBushkin
  • 129,300
  • 32
  • 216
  • 265
  • That sums up my options nicely. Since I won't be needing the key lookup anyway, I'm going with IList. Thanks – Boris Callens Jun 19 '10 at 20:37
  • The [`OrderedDictionary.Remove`](https://learn.microsoft.com/en-us/dotnet/api/system.collections.specialized.ordereddictionary.remove) has [O(N) complexity](https://stackoverflow.com/questions/2565455/what-is-the-complexity-of-ordereddictionary), because each time you remove an entry all entries above it are moved down. So this collection doesn't replicate on every aspect the performance characteristics of a dictionary. – Theodor Zoulias Feb 23 '23 at 21:31
2

You might want to roll one using a Queue<T> where T is a KeyValuePair<string, string>. It's a more solid contract that explicitly guarantees insertion order.

http://msdn.microsoft.com/en-us/library/7977ey2c.aspx

Andy_Vulhop
  • 4,699
  • 3
  • 25
  • 34
  • A `Queue` doesn't support removing specific elements from the collection. You can only dequeue the element that is at the head of the queue. So it can't be used as the basis for a fully functional dictionary. – Theodor Zoulias Feb 23 '23 at 21:23
0

You should just be able to use a List<KeyValuePair<string,string>>. I can't actually find in the MSDN documentation stating that the insertion order is guaranteed, but it's a pretty safe bet...

BFree
  • 102,548
  • 21
  • 159
  • 201