views:

271

answers:

6

I just lifted this snippet from a website and it proved to be exactly the solution I needed for my particular problem.

I have no idea what it is (particularly the delegate and return parts) and the source doesn't explain it.

Hoping SO can enlighten me.

myList.Sort(  delegate(KeyValuePair<String, Int32> x, KeyValuePair<String, Int32> y) 
              { 
                return x.Value.CompareTo(y.Value); 
              }
            );
+1  A: 

It is a sort function called on a list and the thing being passed into it is a delegate which is called by Sort() to actually do the comparison between two elements.

MSDN page on the function http://msdn.microsoft.com/en-us/library/0e743hdt.aspx

stimms
+12  A: 

MyList.Sort has one parameter - the function that is responsible for comparing items, so the list can be sorted accoding to it.

Next: delegate(x,y) defines the function itself which accepts two parameters of type KeyValuePair[String, Int32].

The content in the brackets {...} is the actual comparisson logic:

return x.Value.CompareTo(y.Value);

which compares 2 integer values according to this definition.

Thus your list will be sorted based on the values of those integers in the accending order.


With C# 3.5 I would rewrite it like this:

mylist.Sort((x,y) => x.Value.CompareTo(y.Value));
Dmytrii Nagirniak
With C# 3.0, can this code be shortened?
Chris
Yes. I updated the answer.
Dmytrii Nagirniak
So under the hood, I'm assuming there's something like this going on:for each keyvaluepair in this list, compare the 'value' item in the current keyvaluepair with the 'value' item in the next keyvaluepair. the one that is greater is placed one slot higher than the other.-am I close?
fieldingmellish
Oh, it uses Quick Sort - now I totally get it. thanks all.
fieldingmellish
A: 
myList.Sort //Sort using a your own compare function
  (
    // declare the compare function, returns a int, and receives two items
    delegate(KeyValuePair<String, Int32> x, KeyValuePair<String, Int32> y) 
    {
        // returns a int indicating whether the items are "equal" - equal being what is implemented it the appropriate compare function.
        return x.Value.CompareTo(y.Value);
    }
  );
Am
I believe it actually returns an int, with 0 being equal, less than 0 being x < y, and greater than 0 being x > y
Davy8
It returns INT, NOT BOOLEAN!
Dmytrii Nagirniak
A: 

Think about it this way. Say you had a method that looked like this:

public int MyComparisonMethod(KeyValuePair<string, int> x, KeyValuePair<string,int> y)
{
   return x.Value.CompareTo(y.Value);
}

This basically takes two values, and compares them. It returns a -1 , 0 or 1 depending if x is less than, equal to or greater than y respectively.

Now, under the covers, List.Sort used the Quick Sort algorithm. All you need to understand is, that it keeps comparing various elements in your list against each other. How does it know if value a is greater than, less than or equal to value b? It calls this method, and based on that, it knows. Makes sense?

So the idea is, you provide a mechanism for comparing two values in your list, an the List.Sort uses that to do the comparisons it needs for sorting.

BFree
A: 

Just an FYI,

This is commonly used in the case you need to sort a list of custom classes.

For e.g.

class Student
{
    int rollID;
    string name;
}

List<Student> students = new List<Student>();

...

students.Sort(delegate(Student x, Student y) { return x.rollID.CompareTo(y.rollID);});
Rashmi Pandit
A: 

It is implicit, but may be you should have mentioned the declaration of your "myList". let me write it for you.

var myList=new List<KeyValuePair<string, int>>();

Now, what it means is that each item in this list is an instance of KeyValuePair[string,int].

Now, coming to your question.

One of the overloads of Sort method accepts a "Comparison" delegate, which takes two items of a collection and returns an integer number.

public delegate int Comparison<T>(T x, T y)

Essentially, what you are doing is creating an anonymous delegate which compares two items (in your case, you are sorting on 'Value' you can even sort on 'Key') using the "CompareTo" method of IComparable (string and int implement this interface).

IComparable.CompareTo returns an integer (which is used by Sort method to arrange the items in your list) stating that lhs is less than (-1), greather than (1) or equal to (0) rhs.

FYI: In case you are working on C# 3.0, you dont even need anonymous delegate. You can use lambda expression instead (it is a shorthand to define anonymous delegate, more? )

eg:

myList.Sort((x, y) => x.Value.CompareTo(y.Value));
//Sort over Value

myList.Sort((x, y) => x.Key.CompareTo(y.Key));
//Sort over key

Hope the explanation is helpful.

Amby