Sunday, 1 February 2015

new function: sort-by

Wrote another new function today, didn't take long. This thing is called the sort-by operator, and does pretty much what it says. Instead of having to sort lists indirectly using "clean coeff-sort op-self "" |some list>" as I did in my last post, we can now do it directly: sort-by[op] "" |some list>. (also now means we have less need for op-self operators, but presumably they are still useful somewhere)

General usage:
sort-by[op] some-superposition
one common usage is to use in combination with the table function operator.

Let's use the Australian cities example again:
```sa: load pretty-print-table-of-australian-cities.sw

-- sort by ket lables:
-- (though in this case |city list> is already in the right order)
sa: table[city,area,population,annual-rainfall] ket-sort "" |city list>
+-----------+------+------------+-----------------+
| city      | area | population | annual-rainfall |
+-----------+------+------------+-----------------+
| Adelaide  | 1295 | 1158259    | mm: 600.5       |
| Brisbane  | 5905 | 1857594    | mm: 1146.4      |
| Darwin    | 112  | 120900     | mm: 1714.7      |
| Hobart    | 1357 | 205556     | mm: 619.5       |
| Melbourne | 1566 | 3806092    | mm: 646.9       |
| Perth     | 5386 | 1554769    | mm: 869.4       |
| Sydney    | 2058 | 4336374    | mm: 1214.8      |
+-----------+------+------------+-----------------+

-- sort by area:
sa: table[city,area,population,annual-rainfall] sort-by[area] "" |city list>
+-----------+------+------------+-----------------+
| city      | area | population | annual-rainfall |
+-----------+------+------------+-----------------+
| Darwin    | 112  | 120900     | mm: 1714.7      |
| Adelaide  | 1295 | 1158259    | mm: 600.5       |
| Hobart    | 1357 | 205556     | mm: 619.5       |
| Melbourne | 1566 | 3806092    | mm: 646.9       |
| Sydney    | 2058 | 4336374    | mm: 1214.8      |
| Perth     | 5386 | 1554769    | mm: 869.4       |
| Brisbane  | 5905 | 1857594    | mm: 1146.4      |
+-----------+------+------------+-----------------+

-- sort by population:
sa: table[city,area,population,annual-rainfall] sort-by[population] "" |city list>
+-----------+------+------------+-----------------+
| city      | area | population | annual-rainfall |
+-----------+------+------------+-----------------+
| Darwin    | 112  | 120900     | mm: 1714.7      |
| Hobart    | 1357 | 205556     | mm: 619.5       |
| Adelaide  | 1295 | 1158259    | mm: 600.5       |
| Perth     | 5386 | 1554769    | mm: 869.4       |
| Brisbane  | 5905 | 1857594    | mm: 1146.4      |
| Melbourne | 1566 | 3806092    | mm: 646.9       |
| Sydney    | 2058 | 4336374    | mm: 1214.8      |
+-----------+------+------------+-----------------+

-- reverse sort by population:
-- NB: the "reverse" operator in there
sa: table[city,area,population,annual-rainfall] reverse sort-by[population] "" |city list>
+-----------+------+------------+-----------------+
| city      | area | population | annual-rainfall |
+-----------+------+------------+-----------------+
| Sydney    | 2058 | 4336374    | mm: 1214.8      |
| Melbourne | 1566 | 3806092    | mm: 646.9       |
| Brisbane  | 5905 | 1857594    | mm: 1146.4      |
| Perth     | 5386 | 1554769    | mm: 869.4       |
| Adelaide  | 1295 | 1158259    | mm: 600.5       |
| Hobart    | 1357 | 205556     | mm: 619.5       |
| Darwin    | 112  | 120900     | mm: 1714.7      |
+-----------+------+------------+-----------------+

-- sort by annual-rainfall:
sa: table[city,area,population,annual-rainfall] sort-by[annual-rainfall] "" |city list>
+-----------+------+------------+-----------------+
| city      | area | population | annual-rainfall |
+-----------+------+------------+-----------------+
| Adelaide  | 1295 | 1158259    | mm: 600.5       |
| Hobart    | 1357 | 205556     | mm: 619.5       |
| Melbourne | 1566 | 3806092    | mm: 646.9       |
| Perth     | 5386 | 1554769    | mm: 869.4       |
| Brisbane  | 5905 | 1857594    | mm: 1146.4      |
| Sydney    | 2058 | 4336374    | mm: 1214.8      |
| Darwin    | 112  | 120900     | mm: 1714.7      |
+-----------+------+------------+-----------------+
```
I guess that is all kind of obvious and clear.

Update: Had bug after bug trying to handle sorting by numbers in some cases, text in others, and then the mixed case when the rest are numbers, but some are the empty string (which happens when you hit a |>). Anyway, swapped in a "natural sort" and it all seems to work! Cool. Natural sort should also neatly handle the case when an operator applied to different kets returns different data-types. eg, height data mixing cm and feet, say.