REBOL 3 Docs | Guide | Concepts | Functions | Datatypes | Errors |
TOC < Back Next > | Updated: 6-Feb-2009 Edit History |
The sort function offers a simple, quick method of sorting series. It is most useful for blocks of data, but can also be used on strings of characters.
The simplest examples of sort are:
names: [Eve Luke Zaphod Adam Matt Betty]
probe sort names
[Adam Betty Eve Luke Matt Zaphod]
print sort [321.3 78 321 42 321.8 12 98]
12 42 78 98 321 321.3 321.8
print sort "plosabelm"
abellmops
Notice that sort is destructive to its argument series. It reorders the original data. To prevent this, use copy, as in the following example:
probe sort copy names
By default, sorting is case insensitive:
print sort ["Fred" "fred" "FRED"]
Fred fred FRED
print sort "G4C28f9I15Ed3bA076h"
0123456789AbCdEfGhI
Providing the /case refinement makes sorting case sensitive:
print sort/case "gCcAHfiEGeBIdbFaDh"
ABCDEFGHIabcdefghi
print sort/case ["Fred" "fred" "FRED"]
FRED Fred fred
print sort/case "g4Dc2BI8fCF9i15eAd3bGaE07H6h"
0123456789ABCDEFGHIabcdefghi
Many other datatypes can be sorted:
print sort [1.3.3.4 1.2.3.5 2.2.3.4 1.2.3.4]
1.2.3.4 1.2.3.5 1.3.3.4 2.2.3.4
print sort [$4.23 $23.45 $62.03 $23.23 $4.22]
$4.22 $4.23 $23.23 $23.45 $62.03
print sort [11:11:43 4:12:53 4:14:53 11:11:42]
4:12:53 4:14:53 11:11:42 11:11:43
print sort [11-11-1999 10-11-9999 11-4-1999 11-11-1998]
11-Nov-1998 11-Apr-1999 11-Nov-1999 10-Nov-9999
print sort [john@doe.dom jane@doe.dom jack@jill.dom]
jack@jill.dom jane@doe.dom john@doe.dom
print sort [%user.r %rebol.r %history.r %notes.html]
history.r notes.html rebol.r user.r
Often it is necessary to sort a data set that has more than one value per record. The /skip refinement supports this for sorting records that have a fixed length. The refinement takes one additional argument: an integer specifying length of each record.
Here is an example that sorts a block that contains first name, last name, ages, and emails. The block is sorted by its first column, first-name.
names: [ "Evie" "Jordan" 43 eve@jordan.dom "Matt" "Harrison" 87 matt@harrison.dom "Luke" "Skywader" 32 luke@skywader.dom "Beth" "Landwalker" 104 beth@landwalker.dom "Adam" "Beachcomber" 29 adam@bc.dom ] sort/skip names 4 foreach [first-name last-name age email] names [ print [first-name last-name age email] ] Adam Beachcomber 29 adam@bc.dom Beth Landwalker 104 beth@landwalker.dom Evie Jordan 43 eve@jordan.dom Luke Skywader 32 luke@skywader.dom Matt Harrison 87 matt@harrison.dom
The /compare refinement allows you to perform custom comparisons on the data being sorted. This refinement takes an additional argument, which is the comparison function to use for ordering the data.
A comparison function is written as a regular function that takes two arguments. These arguments are the values to be compared. A comparison function returns true if the first value should be placed before the second value and false if the first value should be placed after the second value.
A normal comparison places data in ascending order:
ascend: func [a b] [a < b]
If the first value is less than the second, then true is returned from the function and the first value is placed before the second value.
data: [100 101 -20 37 42 -4]
probe sort/compare data :ascend
[-20 -4 37 42 100 101]
Similarly:
descend: func [a b] [a > b]
If the first value is greater than the second value, then true is returned and the data is sorted with greater values first. The sort will descend from greater values.
probe sort/compare data :descend
[101 100 42 37 -4 -20]
Notice that in both cases the comparison function is passed by providing its name preceded with a colon. The name preceded with a colon causes the function to be passed to sort without first being evaluated. The comparison function could also be provided directly with:
probe sort/compare data func [a b] [a > b]
[101 100 42 37 -4 -20]
TOC < Back Next > | REBOL.com - WIP Wiki | Feedback Admin |