1 00:00:00,830 --> 00:00:04,730 Making searches faster isn't the only reason to sort a list. 2 00:00:04,730 --> 00:00:09,460 People can make more sense of information when it's in some logical order. 3 00:00:09,460 --> 00:00:11,560 This usually means sorting. 4 00:00:11,560 --> 00:00:13,280 Let's learn how to sort a list. 5 00:00:14,290 --> 00:00:16,930 If we want to sort the list of names alphabetically, 6 00:00:16,930 --> 00:00:19,800 we can just call the Sort method on the list. 7 00:00:19,800 --> 00:00:24,170 So we'll say students.Sort. 8 00:00:24,170 --> 00:00:26,155 Now let's inspect this student's list again. 9 00:00:28,712 --> 00:00:30,786 This performs an in-place sort, 10 00:00:30,786 --> 00:00:35,450 meaning the sorted items are stored back in the list we called Sort on. 11 00:00:35,450 --> 00:00:37,760 There are multiple sort algorithms. 12 00:00:37,760 --> 00:00:41,460 Some sort algorithms work well for small lists, others work well for 13 00:00:41,460 --> 00:00:45,020 medium sized lists, and others work best for large lists. 14 00:00:45,020 --> 00:00:47,500 The Sort method picks the best sort algorithm for 15 00:00:47,500 --> 00:00:50,810 the size of the list, we don't even need to think about it. 16 00:00:50,810 --> 00:00:54,540 Numeric types like integer and double have a natural sort order, so 17 00:00:54,540 --> 00:00:59,570 calling Sort on a list of numbers simply sorts them in ascending order. 18 00:00:59,570 --> 00:01:03,938 How do you think the Sort method knows how to sort a list of strings, though? 19 00:01:03,938 --> 00:01:07,090 It might appear obvious if the strings are all English and 20 00:01:07,090 --> 00:01:09,840 they only contain letters A through Z. 21 00:01:09,840 --> 00:01:13,460 But what if there are numbers or other symbols in the string? 22 00:01:13,460 --> 00:01:16,480 What if there are non-english characters in it? 23 00:01:16,480 --> 00:01:18,550 What should the sort order be then? 24 00:01:18,550 --> 00:01:23,140 How can the Sort method know how to sort any kind of object? 25 00:01:23,140 --> 00:01:24,050 The truth is, 26 00:01:24,050 --> 00:01:28,810 it can't, we need to tell the Sort method how to sort the items in the list. 27 00:01:28,810 --> 00:01:31,450 There are a few different ways to do this. 28 00:01:31,450 --> 00:01:35,330 The reason the Sort method seems to magically know how to sort various types 29 00:01:35,330 --> 00:01:39,230 of objects is because they implement the IComparable interface. 30 00:01:39,230 --> 00:01:42,940 Let's take a look at the MSDN documentation for the string type. 31 00:01:43,960 --> 00:01:47,915 So let's search for System.String. 32 00:01:51,138 --> 00:01:55,661 Here we see that it implements both the IComparable and 33 00:01:55,661 --> 00:01:59,100 IComparable of string interfaces. 34 00:01:59,100 --> 00:02:03,596 Let's a take a look at the documentation for the IComparable generic interface. 35 00:02:07,263 --> 00:02:12,410 We want the generic version, so we want the one that says IComparable(T) here. 36 00:02:12,410 --> 00:02:19,170 Just like we can have generic classes like list, we can also have generic interfaces. 37 00:02:19,170 --> 00:02:23,400 We can see here that any class that implements this interface 38 00:02:23,400 --> 00:02:25,635 will have a method named CompareTo. 39 00:02:26,700 --> 00:02:30,740 This method is used to compare the object that the method is called on 40 00:02:30,740 --> 00:02:32,650 with the item passed in. 41 00:02:32,650 --> 00:02:37,580 This T here acts as a placeholder for the actual type of object passed in. 42 00:02:39,690 --> 00:02:43,310 Notice that CompareTo returns an integer. 43 00:02:43,310 --> 00:02:45,800 CompareTo returns a negative number 44 00:02:45,800 --> 00:02:49,320 if the object should be ordered before the object passed in. 45 00:02:49,320 --> 00:02:52,750 It returns a positive number if the object should be ordered after 46 00:02:52,750 --> 00:02:54,240 the object passed in. 47 00:02:54,240 --> 00:02:57,240 And it returns zero if the objects are equivalent. 48 00:02:57,240 --> 00:02:59,680 Let's see what this looks like in code. 49 00:02:59,680 --> 00:03:03,840 Let's create a new file and name it Students.cs. 50 00:03:03,840 --> 00:03:07,334 Here, we'll write a class to hold details about students. 51 00:03:09,482 --> 00:03:13,567 So we'll say, namespace Treehouse. 52 00:03:13,567 --> 00:03:16,270 And then we'll name our class Student. 53 00:03:16,270 --> 00:03:19,420 To make it so it can be sorted inside of a list, 54 00:03:19,420 --> 00:03:25,040 let's have it implement the System.IComparible interface. 55 00:03:26,420 --> 00:03:28,430 We needed to compare with other students. 56 00:03:28,430 --> 00:03:31,543 So the type parameter here we'll pass in is Student. 57 00:03:34,082 --> 00:03:38,990 The thing we enter here between the angle brackets is called the type parameter. 58 00:03:38,990 --> 00:03:43,240 This is specifying that Student can be compared with other objects 59 00:03:43,240 --> 00:03:44,720 of type Student. 60 00:03:44,720 --> 00:03:48,240 Now, inside the class, let's have two properties. 61 00:03:48,240 --> 00:03:51,520 Let's have string property to hold the student's name. 62 00:03:51,520 --> 00:03:57,979 So we'll say, public string Name, with a getter and a setter. 63 00:04:00,968 --> 00:04:04,768 We'll also have an integer that holds the student's grade level. 64 00:04:04,768 --> 00:04:08,962 Say public int GradeLevel. 65 00:04:12,343 --> 00:04:15,640 This GradeGevel property will tell us if they're in first, second, or 66 00:04:15,640 --> 00:04:16,783 third grade, and so on. 67 00:04:19,121 --> 00:04:23,380 Finally, let's implement the IComparable interface. 68 00:04:23,380 --> 00:04:26,450 For that, we need to add the CompareTo method. 69 00:04:26,450 --> 00:04:33,187 So we'll say, public int CompareToStudent. 70 00:04:33,187 --> 00:04:35,380 And we'll call the student passed in, that. 71 00:04:36,700 --> 00:04:41,490 We'll have it first sort by the student's name and then by grade level. 72 00:04:41,490 --> 00:04:45,514 So I'll say int result = 73 00:04:45,514 --> 00:04:52,620 this.Name.CompareTo(that.Name). 74 00:04:52,620 --> 00:04:57,838 Notice that we can call CompareTo on the properties of the class 75 00:04:57,838 --> 00:05:02,963 because string also implements the IComparable interface. 76 00:05:02,963 --> 00:05:10,070 So if this.Name is the same as that.Name, then the result will be equal to 0. 77 00:05:10,070 --> 00:05:16,500 So we'll say if result = 0, then we need to compare the grade levels. 78 00:05:16,500 --> 00:05:25,000 So we'll say, result = this.GradeLevel.CompareTo. 79 00:05:25,000 --> 00:05:29,629 Int also has a CompareTo method because it also implements the IComparable interface. 80 00:05:29,629 --> 00:05:33,685 So we'll say CompareTo(that.GradeLevel). 81 00:05:35,311 --> 00:05:43,377 Finally, we'll return the result Let's exit out of the csharp REPL. 82 00:05:47,141 --> 00:05:50,920 And let's compile this to make sure we haven't introduced any compiler errors. 83 00:05:50,920 --> 00:05:55,601 So we'll say mcs *.cs. 84 00:05:55,601 --> 00:05:57,620 All right, looks pretty good. 85 00:05:57,620 --> 00:06:01,200 Now, over in Program.cs, we have our Main method. 86 00:06:02,330 --> 00:06:05,110 Let's create a list of students and then sort them. 87 00:06:06,200 --> 00:06:10,318 So I'll say List and 88 00:06:10,318 --> 00:06:15,618 call it students = new List. 89 00:06:15,618 --> 00:06:17,256 And here we'll create three students. 90 00:06:17,256 --> 00:06:25,838 So we'll say, new Student() { Name =, say, "Sally". 91 00:06:28,586 --> 00:06:36,034 GradeLevel is, she's in third grade. 92 00:06:36,034 --> 00:06:37,769 And let's just copy this. 93 00:06:44,667 --> 00:06:52,611 And change these, so I'll say this is Bob, Also in third grade. 94 00:06:52,611 --> 00:06:54,735 Let's put another Sally in second grade. 95 00:06:58,169 --> 00:07:01,691 All right, };. 96 00:07:01,691 --> 00:07:05,290 Now let's call sort on our student list. 97 00:07:05,290 --> 00:07:10,620 So well say students.Sort(). 98 00:07:10,620 --> 00:07:13,140 Now let's print them out to see how they've been sorted. 99 00:07:13,140 --> 00:07:20,264 So we'll say foreach(Student student in students), 100 00:07:22,615 --> 00:07:27,599 Console.WriteLine. 101 00:07:27,599 --> 00:07:31,203 And we'll use a format string, so we'll type a $. 102 00:07:31,203 --> 00:07:36,427 And then inside the curly braces here, 103 00:07:36,427 --> 00:07:41,178 we'll say {student.Name} is in 104 00:07:41,178 --> 00:07:45,941 grade {student.GradeLevel.} 105 00:07:50,193 --> 00:07:55,800 All right, now let's compile this and run it to see our sorted list of students. 106 00:07:57,780 --> 00:07:59,094 We got some compiler errors here. 107 00:08:01,123 --> 00:08:05,460 Looks like we forgot to put System.Collections.Generic. 108 00:08:05,460 --> 00:08:11,096 So let's put using System.Collections.Generic, 109 00:08:11,096 --> 00:08:14,900 can't forget our using directive. 110 00:08:17,190 --> 00:08:21,405 We're getting this because we're missing the using System namespace. 111 00:08:21,405 --> 00:08:23,863 So we'll say, using System;, up here, too. 112 00:08:28,779 --> 00:08:31,021 All right, now let's run our program. 113 00:08:31,021 --> 00:08:34,407 So, do ls to see, okay, we got program.exe. 114 00:08:34,407 --> 00:08:37,980 We'll say mono Program.exe. 115 00:08:39,150 --> 00:08:43,850 All right, we've got Bob is in grade 3, Sally's in grade 2 and Sally's in grade 3. 116 00:08:43,850 --> 00:08:47,200 We were able to sort objects of type Student here 117 00:08:47,200 --> 00:08:49,520 because we wrote the Student class. 118 00:08:49,520 --> 00:08:53,790 So we got to decide how to implement the CompareTo method. 119 00:08:53,790 --> 00:08:57,570 Sometimes, we want to sort things that we don't control the source code for. 120 00:08:57,570 --> 00:09:01,600 So we can't make it implement the IComparable interface like we did here. 121 00:09:01,600 --> 00:09:04,480 Or sometimes we want them ordered differently 122 00:09:04,480 --> 00:09:07,430 than how the class says they should be sorted. 123 00:09:07,430 --> 00:09:08,350 In that case, 124 00:09:08,350 --> 00:09:12,900 there are a couple other ways to tell the list how to sort the objects. 125 00:09:12,900 --> 00:09:16,780 Let's take a look at the documentation for the List class. 126 00:09:16,780 --> 00:09:20,609 So we can find that by searching for 127 00:09:20,609 --> 00:09:26,251 System.Collections.Generic.List. 128 00:09:26,251 --> 00:09:28,398 Here we go. 129 00:09:28,398 --> 00:09:31,080 Let's search this page for the word Sort. 130 00:09:32,210 --> 00:09:34,170 So I'll type in Sort. 131 00:09:34,170 --> 00:09:38,560 And then we can jump down to the methods by adding an open parenthesis here. 132 00:09:38,560 --> 00:09:42,670 As you can see, there are four overloads of the Sort method. 133 00:09:42,670 --> 00:09:45,750 This first Sort method will throw in an exception 134 00:09:45,750 --> 00:09:50,260 if it's called on a list of objects that don't implement the IComparable interface. 135 00:09:50,260 --> 00:09:53,400 If we want to list the sort differently than the way the object says it 136 00:09:53,400 --> 00:09:57,970 should be sorted, or if the objects don't implement the IComparable interface, 137 00:09:57,970 --> 00:10:00,880 we can call one of these other three methods here. 138 00:10:00,880 --> 00:10:05,090 This one takes a special type of object called a delegate. 139 00:10:05,090 --> 00:10:07,700 A delegate is a function that can be passed around 140 00:10:07,700 --> 00:10:10,020 just like any other type of object. 141 00:10:10,020 --> 00:10:13,420 Functions and delegates can be called just like methods. 142 00:10:13,420 --> 00:10:16,770 We'll learn more about delegates in another course. 143 00:10:16,770 --> 00:10:18,762 This is a generic delegate. 144 00:10:18,762 --> 00:10:23,920 We can see that because it has a here. 145 00:10:23,920 --> 00:10:27,090 Essentially, the Sort method can call this delegate and 146 00:10:27,090 --> 00:10:29,870 pass it two objects that it wants to sort. 147 00:10:29,870 --> 00:10:34,410 And the delegate returns an integer just like the CompareTo method does. 148 00:10:34,410 --> 00:10:37,830 This is actually how most people call the Sort method, and 149 00:10:37,830 --> 00:10:40,840 you'll see examples of how to use this in other courses. 150 00:10:40,840 --> 00:10:44,990 This third method here takes an ICompare object. 151 00:10:44,990 --> 00:10:48,250 Let's take a look at the documentation for ICompare. 152 00:10:55,753 --> 00:10:57,730 Again, we want the generic version here. 153 00:10:58,740 --> 00:11:01,160 To tell the Sort method how to sort, 154 00:11:01,160 --> 00:11:05,100 we can create a class that implements the ICompare interface. 155 00:11:05,100 --> 00:11:09,092 It has a single method and it takes two parameters of the same type. 156 00:11:12,352 --> 00:11:16,690 This type here is the generic specified type parameter. 157 00:11:16,690 --> 00:11:19,850 The compare method works just like the CompareTo method 158 00:11:19,850 --> 00:11:21,670 in the IComparable interface. 159 00:11:21,670 --> 00:11:25,700 We can pass an instance of this object to the Sort method, and it will call 160 00:11:25,700 --> 00:11:29,860 the Compare method in order to determine the order of the objects in the list. 161 00:11:29,860 --> 00:11:32,550 We won't implement the ICompare interface here. 162 00:11:32,550 --> 00:11:35,540 Instead, I'm going to leave this as an exercise for 163 00:11:35,540 --> 00:11:38,710 you to practice implementing generic interfaces. 164 00:11:38,710 --> 00:11:43,381 You can refer back to the IComparerable example we have back here in the Student 165 00:11:43,381 --> 00:11:43,891 class. 166 00:11:43,891 --> 00:11:48,090 Or you can also look down here at the bottom of this page for an example.