This tutorial assumes that you know the basic of list. If not, please go over the basic list tutorial. Also you need to know how to use for each number block.
Sorting is arranging of items in a specific order/sequence. There are many algorithms that can be used to sort a list. Here, we will be using Bubble Sort. Bubble Sort is very easy. You start at the beginning of the list, compare each pair of adjacent items and swap if they are not in order. You stop comparing when there is no more items left to compare.
Below is a gif image taken from Wikipedia that shows comparing each pair and swap them if the latter one is smaller/lower than the former one so that the numbers are arranged from smallest to highest which is known as ascending order.
Now that you know about bubble sort, we will go explain how we came up with the procedure SortAndGetList below, step by step. This sort procedure is kind of generic, meaning you can use it for sorting numbers and text both. You can use this procedure for sorting in both ascending and descending orders. Please take note of the numbers in black in the image below as these will be used to describe the purpose of each set of blocks.
We used a procedure result block for sorting. Our procedure SortAndGetList sorts the list in a given order and returns the sorted list. It takes three arguments as follows:
listToSort - This is the list that we want to sort.
order - This tells us how to sort, ascending or descending.
comparisonMode - There are times we will be expecting a list to contain only numbers, sometimes only texts/strings, and sometimes a mixture of both. For numbers, we can easily use Math block's different operators (=, ≠, >, ≥, <, ≤) to compare two items, but we cannot use those for comparing text/strings as texts are not numbers. In that case, we should use the operators from Text block. For Text block, the comparison uses the alphabetical representation of each character in a piece of text. Please go over the documentation on Text block for better grasp. In Text mode, "a" is higher than "A"; "2" is higher than "11". Each character has a decimal/numerical representation in Text mode. For instance, the decimal value of 'A' is 65, 'B' is 66, 'a' is 97, '0' is 48, '2' is 50 etc. You can look at the ASCII table for details.
2. We used a do block which acts as a holder/container for result slot. Take a good look at it and you will notice at the bottom of that do block, there's a result slot which is used to plug the result into so that when some other procedures call this procedure above, they will receive the result plugged into do block.
3. First we check if the list contains at least two items, if not, then there's not really enough elements to sort as sorting of one element will return that element. Also if you remove that block and the list contains say one item, your app will encounter an error since in the second for each number block we have set from as "number + 1", but the first element in the list has a position/index of 1, so "number + 1" will be 2 in the first iteration of the second/nested for each number block which doesn't exist in a list with one item.
4. If you have read on bubble sort algorithm as advised above, you know that we need to compare each adjacent pair. For us to do that, we need one loop to get the items starting from the beginning of the list to the item second to the last in the list to compare. We are not going to compare the last item because there'll be no item after the last item obviously to compare with. Don't worry; by that time the last item will be in order as you will see as we move along. In the image above, you can see that in our first for each number, we have a variable named "number" with an initial from value of 1 (because first item in any list is at index 1), increments by 1 (because we want to go through each item) after each iteration, and our loop executes until (to) the value of "number" reaches length of the list minus 1.
5. In the first for each number block, we get an item at position defined by the value of "number" (e.g. if number is 1, we get the first item) and our goal is to compare the item at position pointed by "number" variable with the rest. So, we need another for each number block to get the rest. That is why we have the second for each number block where we have an argument named "number2", starts from "number + 1" because we want to compare the next item pointed by "number". We compare each until the end of list including the last item. That is why we didn't include the last item in the first for loop.
6. We just re-initialized our global variable status to false which we will need later. It's always better to reinitialize a global variable to its default value for the operation you are performing because other procedures might have used the global variable and changed the value to something else than expected.
7. Storing the item at position pointed by "number" in the list to our global variable named dataHolder1 for later use.
8. We are storing the item at index of "number2" to our global variable named dataHolder2.
9. We check if we should sort the items in ascending order. If so-
10. We need to check if the list should be sorted in number mode, if yes-
11. We compare the item at position "number" with the item at position "number2" using Math block's ">" operator, and swap the items/values at index "number" and "number2" in the list if the item at position "number" is greater/higher than the item at position "number2" since we will be sorting them in ascending order. If item at "number" is higher, we set the global variable status to true so that we can swap later.
If not in number mode,
12. We do the same comparison as 11 but this time using the comparison operator from Text block. If item at "number" is higher, we set the global variable status to true so that we can swap later.
If we need to sort the items in descending order-
13. Same as 10, check first if the comparison for Descending order should be in number mode. If yes-
14. This is opposite of 11. We use the "<" operator from Math block since this time around we want to swap only if the item at position "number" is less/lower than item at position "number2" since we are sorting the items in descending order. If item at "number" is lower, we set the global variable status to true so that we can swap later.
If not in number mode,
15. We do the same comparison as 14 but this time using the comparison operator from Text block. If item at "number" is lower, we set the global variable status to true so that we can swap later.
16. We simply check if the value of our global variable status is true, if yes-
17. We replace the item at position "number" with the item at position "number2", and-
18. We replace the item at position "number2" with the item at position "number".
19. The sorting procedure is done. Hence, we return the sorted list. Note that listToSort argument in our SortAndGetList procedure is simply a reference to the actual list we want to sort. So if we make changes in listToSort, we are actually making changes in the original list that was passed when calling/using SortAndGetList. This makes it unnecessary to return the list. You can use the simple procedure block for that matter rather than using a procedure with result block. For having all options explored, I used the latter.
We can call our SortAndGetList procedure like this-
In the snapshot above, userList is a list. As mentioned, you really don't need to assign the result of SortAndGetList to userList because when you pass the userList while calling/using SortAndGetList, the changes made in listToSort in SortAndGetList actually changes the userList, as listToSort is just a reference to the userList.
Also, you can simplify SortAndGetList procedure depending on your needs. If you need a procedure for sorting numbers in ascending order, remove the unnecessary blocks (Numbers in black- 9, 10, 12, 13, 14, 15). Also you can remove order and comparisonMode arguments as you don't need those arguments.
If you need to verify first if a list contains all numbers before you use Math block's operators for comparing (If you use Math block's operators for comparing texts, your app will throw an error), you may want to have another procedure that would check if a list contains only numbers like this-
Download the source ListBlocks.aia from Downloads page and try it for yourself. There are other features/functionalities that are in source but not covered in this tutorial.