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 for 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 simply 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 is now 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 results 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 this six.
So these three are alphabetically ordered
if they were strings.
It's 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 b will be placed before a 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 just 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 an 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 minus 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 an 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 minus one. 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...
So all we would do is to return minus one,
in this case, and return one, in this case.
And so now the array is nicely sorted the other way around.
So let's write 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.
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 minus one.
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 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 the 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 optimal parameter called sort.
And then, if sort is set to true,
then the movements that we're going to 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 or 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, again, in VS Code,
it nicely shows us what we can pass into 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 is still one or two array methods to learn,
and so let's do that in the next video.