Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Let's use LINQ to help us identify what birds are new to our data set before we import them.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
So we've acquired some new birds and
need to be imported into our dataset.
0:00
How would we go about that?
0:05
Let's say someone has uploaded a file
of birds and now we need to cross-match
0:07
it to our dataset to see if there
are any new birds we can add.
0:11
There's another method
in our bird repository
0:15
class that gives us
a list of imported birds,
0:20
var importedBirds =
BirdRepository.loadImportedBirds.
0:25
Okay, let's take a look.
0:31
All right, so we've got a handful.
0:36
Let's make sure we've also got
our list of current birds,
0:40
birds = BirdRepository.LoadBirds().
0:46
Okay, the imported birds list has some
birds that don't exist in our birds list,
0:53
but there are also duplicates.
0:59
In order to add them to our birds list,
1:02
we'll need to figure out which
ones don't already exist.
1:04
The first thing I think
of is using a join.
1:07
Let's clear the console.
1:11
Okay, let's start out with imported birds.
1:15
Let's assign it to a variable newBirds
1:19
= importedBirds.Join our regular birds.
1:24
Then the outer key which
is imported birds,
1:31
I'll call it ib, goes to ib.CommonName.
1:36
And then b, our inner key,
1:40
goes to b.CommonName.
1:46
And then our result (ib,
1:51
b) goes to new {
1:58
ImportedBirds = ib,
2:02
Birds = b }.
2:09
Well, we're only gonna end up with
the birds that are already in our data,
2:12
Since we're using a join.
2:19
But we need the opposite of that.
2:20
How can we get the birds
that aren't in our data?
2:23
We can do this by using
a new type of join.
2:26
It's called an outer join.
2:29
The join operator we used earlier
can also be called an inner join.
2:31
An inner join combines two sequences and
2:36
returns only the elements where the
property values are equal in both sets.
2:39
An outer join still compares two
sequences based on a property value,
2:44
but what it returns is a little different.
2:48
Instead of returning only the elements
in both sequences that share
2:51
the property value, it returns all
the elements from one sequence and
2:54
then only the matching
elements in the next sequence.
2:59
Link will only let us use
a left outer join, but
3:03
there are other types of joins out there.
3:06
If you want to read more about them,
check out the teacher's notes.
3:09
So in a left join, the left sequence, or
3:13
the first one we'll use,
will have all of its elements returned.
3:16
So in order to do this in link, we'll
need to use the group join operator and
3:19
we'll use our imported birds as our
left sequence since we're interested in
3:24
the birds that have been imported but
are not in our birds list yet.
3:28
var newBirds
3:31
= importedBirds.GroupJoin(birds,
3:34
ib => ib.CommonName,
3:43
and b => b.CommonName.
3:48
So this is gonna be pretty much just
like our regular join we just did.
3:54
(ib, b) => new
4:01
{ ImportedBirds = ib,
4:07
Birds = b}).
4:13
Let's take a look at what that looks like.
4:17
So we've got an innumerable
of ImportedBirds,
4:20
and then it looks like we've
got a grouping of Birds.
4:25
Notice that these groupings are empty.
4:28
I bet those are our new birds, and
4:30
these one down here are the ones
that exist in our dataset.
4:32
Well, we need to select only the imported
birds that don't have a match.
4:36
So first we need to flatten out our
groupings of birds with a select many so
4:40
that we can have one bird for
each imported bird in our result.
4:44
But we'll also use that default if
empty operator in order to return null
4:48
if there are no birds in the grouping.
4:53
Do you remember that?
4:55
Let's see how it'll work.
4:57
Let's clear the console.
4:58
var newBirds =
5:02
importedBirds.GroupJoin on
5:06
birds.
5:14
ib => ib.CommonName,
5:17
b => b.CommonName,
5:23
then (ib, b) =>
5:28
new { ImportedBird.
5:33
So I'm specifying singular here instead
of what I did previously because
5:39
the ImportedBird is going to be a single
object because it's the outer sequence.
5:43
And our inner sequence
will be the grouping.
5:49
ImportedBird = ib, and Birds,
5:52
which is our grouping of birds, = b }.
5:56
Then we'll throw in a SelectMany to
flatten out our list of grouped birds.
6:04
So SelectMany group of birds
6:11
goes to gb.birds.DefaultIfEmpty.
6:16
So DefaultIfEmpty() is going to
return null if we have a birds
6:25
grouping with nothing in it.
6:30
Then, (gb,
6:35
b => new { ImportedBird
6:38
= gb.ImportedBird,
6:43
Bird = b }).
6:48
Okay, our new birds.
6:55
All right, now we've got a flat
list with an ImportedBird and
6:56
then a matching bird which is
null if there were no matches.
7:02
So we only care about the imported
birds without a match.
7:08
So let's add a where clause,
7:11
.Where(nb => nb.Bird == null).
7:15
So that returns only
the imported birds that we need.
7:23
But let's get rid of that
bird object that's null.
7:27
Select(nb =>
7:30
nb.ImportedBird.
7:34
Okay, great.
7:42
So let's assign these to a new variable,
var imported.
7:44
Actually, we'll get the history
of the last one we just did, and
7:50
I'm gonna assign that to a new variable.
7:54
var newImportedBirds
7:56
= that, and then I'm gonna call a ToList.
8:05
Okay, now our list is ready to
import into our birds list.
8:12
We can use the AddRange
method on the birds list
8:18
to add our new birds all at once.
8:21
birds.AddRange(newImportedBirds.
8:23
Okay, let's get a new count for our birds.
8:32
Great, and our imported birds
are now in our birds list.
8:37
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up