Jonas: So we're almost finished with this section
and with our application
but one feature that is still missing in our application
is the ability to sort our movements.
And so in this lecture, let's talk about sorting arrays.
Now, sorting is a much-discussed topic in computer science
and there are countless algorithms and methods
of sorting values
and we might actually talk about this a little bit later
in the course.
For now though,
we're simple gonna use JavaScript's built-in sort method.
And let's start here with an array of strings.
And let's call it owners.
So Jonas,
Zach,
Adam,
and Martha.
Okay?
And now all we need to do is owners.sort, okay?
And so indeed, we now get our array here nicely sorted.
So alphabetically from A to Z.
So this works indeed just as expected, right?
Now, this actually mutates the original array.
So if we take a look at owners now,
you will see that it also now is mutated, okay?
And so we have to be very careful with this method.
So this is with strings.
Now let's try it with numbers as well.
So let's use our movements array here one more time.
So I'll start by logging it to the console
so we can see it.
And then let's also log movements.sort.
So give it some more space here,
and if we take a look at the result here,
this time, the result
is not really what we are expecting, right?
These numbers are not at all ordered in any way, are they?
And the reason for this
is that the sort method
does the sorting based on strings, all right?
So that might sound weird
but that is just how it works by default.
So basically, what it does
is to convert everything to strings
and then it does the sorting itself.
And if we look at the result as if they were strings,
then the result actually makes sense.
So the minus here you see always comes first, okay?
So first, you have all the minuses here
and so that's basically alphabetically
the first string that occurs.
And then afterwards, you have this one,
which starts with one before this four
and then before the six.
So these three are alphabetically ordered
if they were strings.
And the same here.
So you have one first, then two, then three,
then four and then seven.
So again, if they were strings,
then this result would make sense.
But they are not strings
and so we have to fix this
and in fact, we can fix this
by passing in a compare callback function
into the sort method.
So this here does not work.
Let's get rid of it
and so let's write movements.sort
and we need to give it a callback function,
and this callback function is called with two arguments
and let's simply call them a and b.
Okay?
And these two parameters here
are essentially the current value and the next value
if we imagine the sort method looping over the array.
However, in order to understand
how the compare function works,
so how this callback function here works
and how we have to write it,
let's just think of a and b
as simply being two consecutive numbers in the array.
And it doesn't matter which ones.
So let's simply take these two.
So 450 and 400.
Okay?
So let's just compare these two.
Now, in our callback function here,
if we return less than zero,
then the value a will be sorted before value b.
And the opposite, if we return a positive value,
then a will be put before b
in the sorted output array, okay?
So let's use that in practice
to sort the movements array in ascending order.
And first, let me just write what I did here.
So if we return something less than zero,
then A will be before B.
But on the other hand, if we return greater than zero,
then B will be before A, okay?
And so we can use this knowledge
to sort our movements array now in ascending order.
So ascending order means that we want to go
from small to large numbers, right?
And to make this easier to understand,
let's analyze the two numbers that we have here.
So we have 450 and -400
and so if we want to sort these two in an ascending order,
then we need to switch them.
So this is a and this is b, right?
But now we want to switch them
to make them in ascending order.
So what we want here is B and then A.
So B, A, right?
And so therefore, we need to return something
that is greater than zero, okay?
Because that's the rule
how the sort callback function works.
So again, in the case basically that A is greater than B,
which is what we have here,
then we want to return something that is greater than zero.
So let's write that.
So if a is greater than b,
return, and let's say one.
And the number here doesn't really matter
as long as it's greater than zero.
And else, or actually let's write it like this,
so if b is greater than a,
then return something negative.
So just -1, okay?
And that's actually it.
So let's log then the movements again here to the console
because here we are mutating the array
and then at this point,
it is already the mutated version
and now as we see here, the array is now indeed sorted
in an ascending order.
All right?
And so that is because basically the sort method
keeps looping over the array
and applying this callback function here
until everything is in an ascending order according
to the rules that we established here.
Okay?
So returning one here basically means
to switch the order and let's write that here.
Switch order
and keep order.
So maybe that makes it also a bit easier to understand.
So if we come back to one of these examples here,
so let's say we have a and b, 200 and 450.
So in this case, we want to keep the order, right?
And so therefore, that's the case
in which we return something less than zero.
So that's what we have here.
And maybe it's easier to read like this,
so a less than b
but of course, it's the exact same thing.
And then here again with our original example,
this first one is greater,
so the order has to be switched
and so here we have that situation
where a is greater than b.
Now, if we wanted to do it the opposite,
so sorting in a descending order,
we would simply do it exactly the other way around.
So all we would do is to return -1 in this case
and return one in this case.
And so now the array is nicely sorted the other way round.
So let's right that here.
So ascending and
descending.
Let's also log the movements here and great.
So this works beautifully
and it's also gonna work for strings
and you can try that out yourself if you want.
Now, if we are working with numbers,
then we can actually simplify this a lot
by simply using some simple math.
So let's take a look again here at our condition.
So we already know that if a is greater than b,
then a minus b would always be something positive, right?
And the same here with a less than b.
So if a is less than b,
then we know that a minus b
is always something negative
and something negative is exactly what we want
to return here, isn't it?
And so what we can do is take this
and improve it dramatically
because in fact, we don't need any of this.
All we need is to say a minus b.
And that's it.
And let's check the result and it still works the same.
So let's recap what we did here.
So again, we already know that if a is greater than b,
then this will be a positive number
and so here we then return that positive number.
It doesn't have to be exactly one.
Just something greater than zero.
Now, if it's the other way around,
if a is less than b, then this operation
will always be a negative number.
And so therefore, then something negative
is returned just as -1.
But again, it can be any number.
And by the way, if we return zero here,
so in case these two values are the same,
then their position simply remains unchanged.
All right?
So let's do the same here.
And so here it is the opposite, so b minus a.
And as always, keep in mind
that we are actually returning this value here.
But we don't have to write the return
because we're using an arrow function.
So you see, it still works the same.
All right, and this is basically most
of what you need to know about sorting arrays with numbers.
Now, if you have a mixed array,
like with strings and numbers together,
then this is not gonna work and I advise you
to simply not to use the sort method
in these cases anyway.
And that's because there's not really a point
in doing so.
But anyway, now that you know how the sort method works,
let's go back to our application
and implement it there.
So let's first see in the demo version what I mean.
So down here we have this Sort button.
And so this sort will basically sort these movements.
So as we click the button,
it will sort them in this descending order,
which actually is an ascending order
because remember, we are starting
to display these movements here from the bottom up.
Okay?
Then as we click it again, it goes back to normal.
So as we keep clicking,
it orders and goes back to normal.
And so let's implement that now.
So we can give us some more space here.
And now we will actually implement the sorting functionality
right in the function that displays the movements.
Okay?
So let's first implement the sorting itself
and then after that, we will implement the clicking
on the button.
So that's right here.
So displayMovements.
All right?
Now, what we're gonna do here
is to add a second parameter,
which is the sort parameter and by default,
we will set it to false.
And now depending on this parameter,
whether it is true or false,
we will then order our movements or not.
So sort the movements or not.
And of course, it is false by default
because well, by default,
we do want to show the movements
just in the order they appear in the array
but then as we click that Sort button,
we will then call this function displayMovements
with sort set to true.
So let's now create a new variable called movements here.
And this variable here, we will define it conditionally.
And actually, we cannot call it movements
because that's already the name here
of the parameters, right?
So let's just call it movs, all right?
And again, we will define it conditionally.
So we say if sort,
and so that's if sort is true,
then we actually want to sort the movements.
So the movements array that we get here as an input.
So movements
but now we cannot do this.
And that's because, keep in mind that the sort method
will then order the actual underlying array.
So the actual movements array as it is
in the account object.
But that's not what we want at all.
All we want is to display a sorted movements array
but we do not want to sort the original underlying data.
So what do we do here?
Well, we simply take a copy of the movements array
and sort that.
And so that's what we use now slice for
and this is one of these situations
that I was telling you about earlier
where we need to actually create a copy,
using the slice method
and not the spread operator
because here we are in the middle of a chain.
And so we want to keep going after this
and so it's a lot better
to simply use the method here
so that we can then simply chain the sort method onto that.
And now all we need here is our compare function.
And now remember how in the user interface,
so in our application,
how the movements appeared in a descending order.
However, that is because we start to display the values
from the bottom up
and so actually, we want to now sort this array
in an ascending order.
And to do that, remember, we do a minus b.
So I explained before why it works this way.
Okay, but now if sort is false,
so that's the default value,
then movs should simply become movements.
Right?
Let's get rid of this comment here.
Give it a save
and now here, of course, we then need to use that movs
that we just created.
And with this, we have essentially adapted
our displayMovements function to support sorting.
And again, we did that by allowing a second parameter,
which is an optional parameter called sort
and then if sort is set to true,
then the movements that we're gonna use
to display them will be sorted like this
and if it's set to false,
then simply the regular movements as they are passed in
will be displayed.
And now all we need to do
is to call this function here
with sort set to true
whenever the user clicks that sort button.
So that button is called btnSort
and so let's now create our final event listener
or event handler here.
So btnSort.addEventListener
and as always, we start by preventing the default.
So you can get used to this.
And then here, we want to call print
and then here we want to call displayMovements
and of course, with currentAccount.movements as always
and then the second parameter we will set to true.
So that's the sort parameter.
And if we ever are in doubt,
then again in VS Code, it nicely shows us
what we can pass in to the function.
So movements and sort.
Now, this is not yet the 100% working solution
and let me show you why.
So as I log in,
let me almost remove this here,
so let's click now the Sort button and beautiful.
That worked.
So the movements are now indeed sorted
but now, if I click the button again,
it will not go back to normal.
Right?
And how could it?
We never told it to do so.
So let's find a way of solving this.
And we will solve this by using a state variable,
which will monitor if we are currently sorting
the array or not.
Okay?
So that variable needs to live outside
of this callback function
so that its value can be preserved
after clicking this button here, right?
Because as you know, this function here
is executed each time that we click the Sort button.
And so if we defined a variable here in this function,
then it would be created newly each time
that we click that button.
And so we want to preserve that sorted state
throughout all the clicks.
So we start with this state variable set to false.
And so that's because in the beginning,
our array is not sorted.
So sorted is false.
And so if it is false,
then here this should be true.
So we then want to actually sort the array.
So basically, here we want the opposite of sorted, right?
And so that's where our not operator comes
in handy, all right?
So we're doing the opposite of sorted.
When sorted is false,
then we want to sort it.
So we need true here.
But if it is already sorted,
then we again want the opposite
and so then sort should be back to false.
Now, the only thing that's missing
is to actually flip this variable, okay?
And so for that,
we do sorted equal the opposite of sorted once again.
And so this is what then allows everything here to work.
Otherwise even as we would click,
this sorted variable would then never change.
And so with this, each time that we click,
we change sorted from true to false,
then from false to true and so on and so forth.
So let's try it now finally.
And
yes,
great, that works beautifully
and so our job here is done.
And in fact, this application
is now complete, at least for this section.
So great job, congratulations for reaching this point,
for finishing this application.
This is really an amazing achievement
and you can pat yourself on the back for making it this far.
Now, there's still one or two array methods to learn
and so let's do that in the next video.