0

I'm trying to get my head around the C# sorted collections such as SortedList and SortedDictionary. I have two main mental blockers and I can't find anywhere that explains them clearly. I understand that there is a default way in which these collections keep themselves sorted, and that you can also specify this.

I suppose my question is simply; How is this done? I can't find any simple examples of how to write these things.

Say for example I wanted a collection to store key value pairs from float to int, I want to be able to grab the int by querying the collection for the lowest float value. In other words I want to get the int with the lowest associated float key. Am I right in thinking that the fact that the collection is sorted makes it more efficient to do this kind of thing? Does this also mean that I can just grab the first element in the collection like: collection[0]? and it will be the lowest? (if i've sorted it that way)

Sorry this question is not more succinct, I'm just not sure where to start.

Dollarslice
  • 9,917
  • 22
  • 59
  • 87
  • Read this: http://stackoverflow.com/questions/935621/whats-the-difference-between-sortedlist-and-sorteddictionary/935631#935631. As for examples: check out MSDN: http://msdn.microsoft.com/en-us/library/ms132319.aspx – RBZ Jul 30 '12 at 22:01

4 Answers4

1

SortedDictionary doesn't give you an integer indexer nor a "get minimum key" function; SortedList does. SortedList is super inefficient, however, if you're inserting the data out of order. You should order it first and then build the list.

If the only function you require that's missing from SortedDictionary is "get minimum key" then you can use the First or FirstOrDefault linq method, since the enumerator returns the key-value pairs in key order. If you need other similar functions (like "get maximum key"), and you also require more efficient insertions and deletions of randomly-distributed values, you should probably make your own implementation of a binary tree (which SortedDictionary is) that exposes these functions.

To implement IComparer<T>, create a new class:

public class FloatComparer : IComparer<float>
{
    public int Compare(float a, float b)
    {
        //your logic goes here; return -1 if a should be considered smaller or 1 if b should be considered smaller
    }
}

Then pass it to the constructor of the sorted collection in the usual way:

var collection = new SortedDictionary<float>(new IComparer<float>());
phoog
  • 42,068
  • 6
  • 79
  • 117
  • so do the collections automatically sort from low to high? – Dollarslice Jul 30 '12 at 22:19
  • @SirYakalot if you don't provide your own `IComparer` instance, the collection will use the default comparer, which sorts from low to high. So the collections sort from low to high by default; in other words, yes, they automatically sort from low to high unless told to do otherwise. – phoog Jul 30 '12 at 22:23
  • AH! I think I see! thank you! sometimes these things are confusing at first. well, for me anyway. – Dollarslice Jul 30 '12 at 22:25
  • so, sorry last question, with a sortedList should I be able to do sortedList[0] to get the int with the lowest float key? – Dollarslice Jul 30 '12 at 22:36
  • @SirYakalot not quite. You would have to do `sortedList.Values[0]` for that. – phoog Jul 30 '12 at 22:39
0

read up on data structures like trees and heaps etc. start with Red Black Tree. I guess that is the classic example. google and wikipedia helps.

Basically the stuff you insert has some kind of a definition which allows it to be compared for larger, equal, smaller than. On insertion the elements are compared and sorted. So when you search for the first or last you know that they are smallest or largest. You can also efficiently check if there is an integer equal to 4 in the structure for example.

Markus Mikkolainen
  • 3,397
  • 18
  • 21
  • thanks, could you provide an example of how you set this up? I understand the theory I just don't know the syntax. – Dollarslice Jul 30 '12 at 22:00
  • Umm i am not sure what you are getting at but in the sortedlist documentation it gives you the option to pass an IComparer interface to the created list as a parameter. Or You can make sure the elements implement an IComparable which defines the ordering. – Markus Mikkolainen Jul 30 '12 at 22:04
  • sure, but what's the syntax? like, how do you actually write it? Like an example. – Dollarslice Jul 30 '12 at 22:15
  • I'm sorry, I'm not trying to be difficult but I really don't understand why you don't get my question. Simply, can you give me an example in code of how you instantiate a sorted collection and how you set the comparison. – Dollarslice Jul 30 '12 at 22:21
  • maybe it is, but that doesn't change the fact that I don't know it! Everyone has to learn something for the first time at some point. Never mind though, as you say he provided an example. – Dollarslice Jul 30 '12 at 22:24
0

The SortedDictionary is a balanced tree, while SortedList is just a continuous slab of memory that happens to contain ordered elements. In both cases, we need to define what "less than" means, so the tree can organize its nodes and the sorted list can order its elements:

  • If you pass an object that implements IComparer to the constructor of these containers, that is what gets used. As long as it is a strict weak ordering it will work fine. For example, it's easy to sort the container in reverse by supplying a "greater than" comparer.
  • Otherwise, a default comparer is used.

In your case (where float is the key), the default comparer will do the right thing and order the elements from lowest to highest value. Getting the first element will be efficient and the first element also happens to be the lowest value.

Branko Dimitrijevic
  • 50,809
  • 10
  • 93
  • 167
0

It's easy.

Say you have a Sorted Dictionary called series that associates an array of doubles with a date.

public SortedDictionary series = new SortedDictionary();

And you have loaded it up with data.

You can get the first item (first in sorted order) as follows:

  var firstItem = series.First();

  firstItem.Key is the first date.

  firstItem.Value is the array of doubles associated with the first date

Happy programming!