views:

97

answers:

4

I am trying to combine two SortedDictionaries, change the result to a List<KeyvaluePair<string,string>> and Sort() the result. The following statement throws an error:

var combinedEntries = from p in leftDict.Union(rightDict).ToList().Sort(myComparer) select p;

Error: Could not find an implementation of the query pattern for source type 'void'. 'Select' not found.

This is not working because Sort() returns void. If I split up the statement, it works:

var combinedEntries = from p in leftDict.Union(rightDict) select p;
List<KeyValuePair<string, string>> finalentries = combinedEntries.ToList();
finalentries.Sort(comparer);

I understand that sort is a method of List type and not IEnumerable, but I thought calling ToList() before Sort() will take care of that problem. So first question is can it be used like I am trying in the first statement? If not, how do I make use of orderby here?

+1  A: 

Sort does not return a value, and combinedEntries is going to take the result of the last called method. Since Sort returns void you are getting an error by attempting to assign void to a variable. Because of this you should keep the Sort "split up" from the rest.

Corey Sunwold
is that the common practice? i thought we could 'chain' all functions in linq queries.
desigeek
Sort isn't a feature of linq, it's a instance method in the List<> class
Mike
Could != should. (You can't do it on .Sort as the fella above me explained, but generally)Chained LINQ is lovely, but results in code that's not as easily readable as it could be with some line breaks. Now, "select x from " style syntax is a different issue.
Rubys
+4  A: 

.Sort() doesn't return a value. It sorts the list in place.

You might want to try using .OrderBy before .ToList() or, you need to end the line at .ToList() so that the list can be assigned to your variable. Then Sort.

var sortedCombined = (from p in leftDict.Union(rightDict)
                      orderby p.Key // or whatever you need
                      select p).ToList();
Mike
+1  A: 

Like this:

var combinedEntries = leftDict.Union(rightDict).OrderBy(kvp => kvp.Key).ToList();
SLaks
my ienumerable is a dictionary.I want to use orderby on the keys of this dict. What will be the syntax for orderby? how do I get the to the keys?
desigeek
+1  A: 

You can do combinedEntries = <query goes here>.OrderBy(a => a, myComparer).ToList();.
However, seperately converting it into a list, and explicitly sorting is much more readable, and I'm willing to bet some good money that List.Sort beats OrderBy in performance easily.

Rubys
both algorithms employ quicksort, so there isn't any noticeable difference.
Femaref
You'd be surprised what some abstraction can do to your performance.I just clocked sorting of 100000 random elements using .OrderBy and using .Sort(). The latter was about 8-10 times faster.
Rubys
You're correct, List.Sort() does a quicksort. Linq.OrderBy does a query, which is a bit more intensive. I'm just curious what Femaref's backing is for his claim of a quicksort on the Linq library. Reflector shows no such evidence.
drachenstern
List.Sort is an in-place sort; LINQ is not.
SLaks
@drachenstern: I can't find it, but I distinctly remember reading that orderby is quicksort aswell.
Rubys