Let's Dive Into Writing Our Custom sort
Function!
Our function will have the same prototype with the other except the name of course 😅. We’ll create a sorting function similar to our previous custom functions, just with a new name and a little extra logic. Here’s how the prototype looks:
function mySort(array, sortCallback) {
// Implementation
}
For the implementation, we will need a sorting algorithm that will sort the array depending on the output of the sortCallback
function. while the purpose of this tutorial is not to learn sorting algorithms, we’ll use a basic sorting algorithm that will allow us to achieve our goal.
The principe of bubble sort algorithm
To sort the array, we’ll use a basic but effective sorting algorithm called Bubble Sort. While not the most efficient for large datasets, it's perfect for demonstrating how sorting works.
Bubble Sort is one of the simplest sorting algorithms. It compares adjacent elements and swaps them if they’re in the wrong order. The process repeats until the entire list is sorted. Here’s how it works:
Compare the first two elements of the list. If the first element is greater than the second, swap them(exchange their position).
Move to the next pair of elements and repeat step 1.
Continue this process until the entire list has been traversed.
Repeat steps 1-3 until the list is fully sorted.
The algorithm gets its name from the way the smaller elements "bubble up" to the top of the list, while the larger elements "sink down" to the bottom.
Check out these resources for a better understanding of the bubble sorting algorithm
Implementation in mySort
function
Let's continue our implementation of mySort
. According to the steps we enumerate, we could have the following implementation
function mySort(array, callback) {
let sorted;
do {
sorted = true;
for (let i = 0; i < array.length - 1; i++) {
if (callback(array[i], array[i + 1]) > 0) {
let temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
sorted = false
}
}
} while (!sorted);
}
What’s Happening Here?
Initial Setup
- We initialize a boolean variable
sorted
totrue
at the start of the loop. This flag helps us track whether any swaps were made during a pass through the array. If no swaps are made, the array is fully sorted, and we can stop the process.
- We initialize a boolean variable
Iterating through the Array
- Inside the
for
loop, we iterate through the array from the first to the second-to-last element (i < array.length - 1
). We do this because we are comparing each element with its next neighbor.
- Inside the
Comparing Adjacent Elements
- The heart of the sorting process is the comparison between
array[i]
andarray[i + 1]
. ThesortCallback
function determines how these two elements should be ordered. If the callback returns a value greater than 0, it meansarray[i]
should be placed afterarray[i + 1]
, so we swap them.
- The heart of the sorting process is the comparison between
Swapping Elements
- If a swap is necessary, we temporarily store
array[i]
in a variabletemp
, then replacearray[i]
witharray[i + 1]
, and finally put the originalarray[i]
value (stored intemp
) intoarray[i + 1]
.
- If a swap is necessary, we temporarily store
Tracking Changes
- When a swap occurs, it means the array is not fully sorted, so we set
sorted = false
to signal that we need another pass through the array.
- When a swap occurs, it means the array is not fully sorted, so we set
Repeating Until Sorted
- The loop continues until a full pass through the array results in no swaps, meaning the
sorted
flag remainstrue
, and the array is fully sorted.
- The loop continues until a full pass through the array results in no swaps, meaning the
Handling Different Sorting Orders
With this structure, our mySort
function can handle both ascending and descending orders or even custom sorting orders depending on how the sortCallback
is defined.
For example, to sort an array of numbers in ascending order, you could call mySort
like this:
const numbers = [5, 3, 8, 1];
mySort(numbers, (a, b) => a - b);
In this case, the callback function (a, b) => a - b
ensures that the smaller number will "bubble" to the left side of the array, and the larger number will "sink" to the right.
For descending order, simply reverse the callback:
mySort(numbers, (a, b) => b - a);
Now, the larger numbers will rise to the top, and the smaller numbers will sink down.
Testing with Other Data Types
The great thing about this approach is its flexibility. You can easily sort arrays of strings, objects, or any other data type, as long as the callback function defines the appropriate comparison logic.
For instance, sorting an array of strings alphabetically:
const fruits = ['apple', 'banana', 'orange'];
mySort(fruits, (a, b) => a.localeCompare(b));
Or sorting an array of objects based on a specific property:
const users = [
{username: 'john', age: 30},
{username: 'doe', age: 26},
{username: 'steeve', age: 29},
{username: 'lorent', age: 24}
];
mySort(users, (a, b) => a.age - b.age);
This is the beauty of using callbacks in our mySort
function, it can handle a wide variety of sorting scenarios!
That’s it for now! Give your new mySort
function a spin, try different callbacks, and see how powerful custom sorting can be.
Final Words
Bubble sort is super easy to understand, which makes it a great place to start learning sorting algorithms. But here’s the thing, it’s not the fastest for big arrays. There is more efficient sorting algorithms like quicksort or mergesort that are much faster for large datasets. But mastering bubble sort first will give you the foundation to tackle those more advanced techniques.
Now it's your turn to give the mySort
function a try! Experiment with different callbacks and see how powerful custom sorting can be. Once you’ve got it down, challenge yourself by implementing more efficient sorting methods. Here are some resources:
Sorting Algorithms - GeeksforGeeks
(23) hungarian dance - sorting algorithms - YouTube
Happy coding! 🚀😀