1 00:00:00,770 --> 00:00:04,690 So far we've been using operators that return an Enumerable. 2 00:00:04,690 --> 00:00:07,950 The next set of operators deal with returning a single element 3 00:00:07,950 --> 00:00:08,680 from a collection. 4 00:00:09,850 --> 00:00:12,420 They're used quite often in LINQ queries. 5 00:00:12,420 --> 00:00:16,630 The Single method will return a single element from our collection. 6 00:00:16,630 --> 00:00:21,129 We can use it without a parameter, like in combination with the Where method. 7 00:00:21,129 --> 00:00:25,091 birds.Where, and don't forget, if you don't have birds, 8 00:00:25,091 --> 00:00:29,490 load up your birds using the instructions in Workspaces. 9 00:00:29,490 --> 00:00:38,350 Where b goes to b.Name == Crow. 10 00:00:38,350 --> 00:00:42,830 And then we'll call .Single. 11 00:00:42,830 --> 00:00:43,860 And there's our crow. 12 00:00:45,110 --> 00:00:48,909 Or we can use the predicate as a parameter. 13 00:00:48,909 --> 00:00:54,651 birds.Single b goes to b.Name 14 00:00:54,651 --> 00:00:59,990 == Crow, and there it is. 15 00:00:59,990 --> 00:01:05,151 What happens if we use the Single method but there isn't a match in the collection? 16 00:01:05,151 --> 00:01:10,096 birds.Single where b goes to 17 00:01:10,096 --> 00:01:14,466 b.Name == Chickadee. 18 00:01:14,466 --> 00:01:16,010 I don't think there's a chickadee in there. 19 00:01:17,870 --> 00:01:18,920 Ouch. 20 00:01:18,920 --> 00:01:21,000 Invalid operation exception. 21 00:01:21,000 --> 00:01:23,890 Sequence contains no matching element. 22 00:01:23,890 --> 00:01:27,910 There's another version of this method, and all of the element operators in LINQ 23 00:01:27,910 --> 00:01:31,645 have this version of their method, SingleOrDefault. 24 00:01:32,880 --> 00:01:37,770 So let's try that one again, but instead of just Single, 25 00:01:37,770 --> 00:01:41,950 I'll tack on OrDefault. 26 00:01:41,950 --> 00:01:43,770 And then it returns null. 27 00:01:43,770 --> 00:01:49,510 So what this method does is if it doesn't find a match, it returns a default value. 28 00:01:49,510 --> 00:01:52,475 So in this case, a bird has a default value of null. 29 00:01:54,000 --> 00:01:58,284 If we were dealing with integers, say, 30 00:01:58,284 --> 00:02:01,812 a list like we were using before, 31 00:02:01,812 --> 00:02:06,350 var numbers = new List of int 2, 4, 8. 32 00:02:06,350 --> 00:02:08,800 All right, that's enough. 33 00:02:10,730 --> 00:02:14,555 And if we use SingleOrDefault to try and get a number that doesn't exist, 34 00:02:14,555 --> 00:02:20,120 Numbers.SingleOrDefault where 35 00:02:20,120 --> 00:02:25,700 n goes to n == 99, 36 00:02:25,700 --> 00:02:30,160 then it returns 0 since the default value for an integer is 0. 37 00:02:30,160 --> 00:02:33,622 So what happens if we use the Single method but 38 00:02:33,622 --> 00:02:36,914 our predicate matches more than one bird? 39 00:02:36,914 --> 00:02:43,600 birds.Single, burned again, InvalidOperationException. 40 00:02:43,600 --> 00:02:46,690 Sequence contains more than one element. 41 00:02:46,690 --> 00:02:49,240 So the Single method will return an exception 42 00:02:49,240 --> 00:02:53,330 if the condition returns more than one element from the sequence. 43 00:02:53,330 --> 00:02:54,560 When we use Single, 44 00:02:54,560 --> 00:02:57,900 we want to make sure that there's only one of its kind in the collection. 45 00:02:59,160 --> 00:03:01,820 You might think, well, I should use SingleOrDefault so 46 00:03:01,820 --> 00:03:03,570 that I don't get an exception. 47 00:03:03,570 --> 00:03:05,860 It depends on what the situation is. 48 00:03:05,860 --> 00:03:09,800 You might want an exception if you are truly looking for an unique object in 49 00:03:09,800 --> 00:03:12,920 the collection and there's more than one, or it doesn't exist. 50 00:03:14,750 --> 00:03:19,050 The next two methods are pretty similar to each other, the First method and 51 00:03:19,050 --> 00:03:20,670 the Last method. 52 00:03:20,670 --> 00:03:23,110 They can be used the same way as Single, but 53 00:03:23,110 --> 00:03:25,920 it's not expected that the element is unique. 54 00:03:25,920 --> 00:03:27,825 Let's get the first bird in our list. 55 00:03:27,825 --> 00:03:32,190 birds.First. 56 00:03:32,190 --> 00:03:33,695 And what's the last bird in our list? 57 00:03:33,695 --> 00:03:36,550 birds.Last. 58 00:03:36,550 --> 00:03:40,537 We can use a predicate just like with the single method. 59 00:03:40,537 --> 00:03:44,831 birds.First where b 60 00:03:44,831 --> 00:03:49,843 goes to b.Color = Red. 61 00:03:51,650 --> 00:03:54,930 And like the single method, if there are no elements that match, 62 00:03:54,930 --> 00:03:55,910 we get an exception. 63 00:03:58,600 --> 00:04:00,970 So let's try that again with Chickadee. 64 00:04:02,760 --> 00:04:06,220 These methods also have the or default versions. 65 00:04:06,220 --> 00:04:09,685 So if we're not sure an element exists, we'll use FirstOrDefault. 66 00:04:13,190 --> 00:04:17,210 Default. 67 00:04:17,210 --> 00:04:18,807 Whoops, forgot the Or. 68 00:04:18,807 --> 00:04:20,685 FirstOrDefault. 69 00:04:20,685 --> 00:04:22,490 Null, and we don't get an exception. 70 00:04:24,310 --> 00:04:28,520 The last method we'll talk about is the ElementAt method. 71 00:04:28,520 --> 00:04:32,470 We can use it to get an element at a certain position in the sequence. 72 00:04:32,470 --> 00:04:37,405 So like with using an indexer on an array, 73 00:04:37,405 --> 00:04:41,640 int of numbers = 0, 1, 2, 3. 74 00:04:44,770 --> 00:04:49,584 And I can access with an indexer like. 75 00:04:49,584 --> 00:04:55,929 But we can also use LINQ to use ElementAt(2) and 76 00:04:55,929 --> 00:04:58,960 it does the same thing. 77 00:05:00,400 --> 00:05:04,410 I personally haven't seen the ElementAt method used much, but 78 00:05:04,410 --> 00:05:07,550 I'm sure there's some edge case where it might be handy. 79 00:05:07,550 --> 00:05:11,908 If your Enumerable is also a list, you can still use the indexer, so 80 00:05:11,908 --> 00:05:16,090 like birds[0]. 81 00:05:16,090 --> 00:05:21,370 But if you've got the result of a LINQ query, which is a pure enumerable, so 82 00:05:21,370 --> 00:05:26,340 var redBirds = birds.Where b 83 00:05:26,340 --> 00:05:30,360 goes to b.Color == Red. 84 00:05:33,177 --> 00:05:36,480 We wouldn't be able to use an indexer to access the items. 85 00:05:37,610 --> 00:05:38,480 redBirds. 86 00:05:40,120 --> 00:05:41,210 Nope. 87 00:05:41,210 --> 00:05:42,968 But you could still use the ElementAt method. 88 00:05:42,968 --> 00:05:49,040 redBirds.ElementAt(0). 89 00:05:50,170 --> 00:05:52,590 And just like the other methods of this type, 90 00:05:52,590 --> 00:05:56,760 we can use OrDefault to avoid an exception if the element doesn't exist. 91 00:05:58,270 --> 00:06:01,913 So redBirds.ElementAt, we'll do 99. 92 00:06:01,913 --> 00:06:09,682 But if we used OrDefault, 93 00:06:09,682 --> 00:06:13,217 just null. 94 00:06:13,217 --> 00:06:15,307 Let's recap these methods. 95 00:06:15,307 --> 00:06:18,620 Single, use when the element must be unique. 96 00:06:18,620 --> 00:06:22,100 Exception if more than one, or none exists. 97 00:06:22,100 --> 00:06:26,470 First, use if there could be more than one, but you only need the first. 98 00:06:26,470 --> 00:06:28,450 Exception if no match. 99 00:06:28,450 --> 00:06:32,490 Last, use if there could be more than one, but you only need the last. 100 00:06:32,490 --> 00:06:34,520 Exception if no match. 101 00:06:34,520 --> 00:06:38,520 ElementAt, use if you know the exact position of the element. 102 00:06:38,520 --> 00:06:39,660 Exception if no match. 103 00:06:40,765 --> 00:06:46,030 SingleOrDefault, use only when the element must be unique, or it may not exist. 104 00:06:47,130 --> 00:06:50,940 FirstOrDefault, use if there could be more than one or none, but 105 00:06:50,940 --> 00:06:51,970 you only need the first. 106 00:06:53,060 --> 00:06:56,260 LastOrDefault, use if there could be more than one or none, 107 00:06:56,260 --> 00:06:57,530 but you only need the last. 108 00:06:58,770 --> 00:07:03,038 And ElementAtOrDefault, use if you know the exact position of the element, but 109 00:07:03,038 --> 00:07:04,243 it might not be there.