TheBritishAreComing
TheBritishAreComing

Reputation: 1717

C# SortedDictionary producing unusual results

I'm working with a SortedDictionary where the key is integer and value is string.

SortedDictionary<int,string> dic = new SortedDictionary<int,string>();

Now say I add values like

dic.Add(100,"String 1");
dic.Add(1113,"String 2");
dic.Add(1,"String 3");
dic.Add(70,"String 4");

and then do a foreach loop like

foreach(string item in dic.Values) {
        Console.WriteLine(item);
}

then the values never come out in the correct order, they come out in an almost random order which is similar behaviour to a normal Dictionary. Anyone got any ideas why? am I missing / doing something wrong?

PS: When I say it's coming out in a random order I mean key order not value so it's coming out like 1113,70,1,100


It seems I may have over simplified the problem, but it shouldn't make a difference, there is a lot of nesting involved and the final dictionary is actually the child of another dictionary which is the child of another!

SortedDictionary<String, SortedDictionary<String, SortedDictionary<int, SortedDictionary<String, String>>>>()

The dictionary i'm looping through is

SortedDictionary<int, SortedDictionary<String, String>>

Here is the loop as requested:

foreach (SortedDictionary<String, String> cDic in openTrades.Values)
{
    String cTimestamp = convertTimestamp(cDic["open"]);
    if (!closeTrades.ContainsKey(cDic["key"]) && barArray.ContainsKey(cDic["pair"]))
    {
          foreach (SortedDictionary<String, String> bDic in barArray[cDic["pair"]][cDic["frame"]].Values)
          {
               //This is the relative Loop
          }
    }
}

barArray is our Primary SortedDictionary (the subject of this question) openTrades is another SortedDictionary

Thanks James

Upvotes: 2

Views: 1905

Answers (4)

Oliver
Oliver

Reputation: 45101

As all the others my first impression was you are confused if the dictionary is sorted by keys and not by values. But reading your comments this doesn't seem the problem.

So i simply (like the others too) pasted the code into Visual Studio and let it run. The output was (as expected):

String 3
String 4
String 1
String 2

If the order differs on your machine, there seems to be something really weird going on there. Maybe you can make another run, but make a little change to your foreach statement:

foreach (var item in dic)
{
    Console.WriteLine(item);
}

Now in item you'll get a KeyValuePair<int, string>, which will nicely printed out like this:

[1, String 3]
[70, String 4]
[100, String 1]
[1113, String 2]

So you'll get another check what exact key belongs to each value you got and maybe find another clue why you get a sorting you don't expect.

Upvotes: 1

BrokenGlass
BrokenGlass

Reputation: 160872

SortedDictionary sorts on the key not the value.

If you do the following

foreach(var item in dic)
{
        Console.WriteLine(item.Key + "-" + item.Value);
}

You will see that it prints out in sorted order by key:

1-String 3
70-String 4
100-String 1
1113-String 2

Upvotes: 8

Bruno Brant
Bruno Brant

Reputation: 8564

The problem lies in your foreach loop. The SortedDictionary class exposes the list of values, but that list isn't sorted, so you are just reading from a unsorted list.


Reading the code again, I realized that the list is being presented in a sorted order. What I think happened is that you got confused because you somehow expected it to sort through the Value field. SortedDictionary sorts through the Key field (the integers in your add statement).

Upvotes: 0

Ed Swangren
Ed Swangren

Reputation: 124642

I'm not sure what you think the output should be, but for me it is

String 3
String 4
String 1
String 2

Which is correct. Perhaps you are under the impression that a SortedDictionary maintains insertion order? A quick review of the documentation will tell you that is not the case. The values are sorted via a Comparer<T> on the key (assuming no custom Comparer is provided.)

Upvotes: 1

Related Questions