Sort an array or a record of arrays

sort()

Sorting arrays

Version >= 6.0.4


SYNTAX

sort(fld | record, nelem, keystring | func)

fld | record

The sort function sorts an array field or a record containing array fields. In the record case, all array fields in the record that have the same dimension as the first sort field are re-ordered, whether or not they form part of the sort key. Array fields that have a different dimension are not re-ordered. Optionally, an index can be specified with the field or record parameter, in which case the sort starts at that index.

Since Sculptor version 6.2.0 records or subrecords can have dimensions. The sort function has been modified to sort a record if it has dimensions (in this case any containing field arrays will not be sorted)

nelem

The number of elements to be sorted (0 = the entire array).

keystring

For a single array field, a text string that specifies the sort order:

a” = ascending - case sensitive if text
d” = descending - case sensitive if text
A” = ascending - case insensitive if text
D” = descending - case insensitive if text

For a record, a text string that specifies the fields to be sorted in order of priority. Each field number must be followed by the sort order for that field as above. For example:

3a2d” means sort by field 3 ascending, then field 2 descending.

func

A Sculptor function that is called to compare values as an alternative to using a keystring. For a record, the first array field in the record specifies the sort dimension and only fields with the same dimension are re-ordered. The function call is:

func(index1, index2)

where index1 and index2 are the subscripts of the array values to be compared. The function must return an integer result:

0   if val1 = val2
< 0 if val1 < val2
> 0 if val1 > val2

Return values:

0

Successful

-1

Nothing to sort (check the keystring and other parameters)

>0

This number of fields specified in the keystring were ignored because they do not exist or because their dimension does not equal the dimension of the first specified sort field.


NOTES

  • The sort command treats a multi-dimension array as a single, large array.

  • Overheads with the function option make it much slower than the keystring option, especially with large, multi-dimension arrays.


EXAMPLE

For complete examples, see sort.r and sortbig.r in sculptor\examples.

!record SourceArray {
    LineNo,"Line No",i4[50000],"##,###,###"
    Integer,"Integer",i4[50000],"###,##0"
    Date,"Date",i4[50000]/dn,"dD/mM/YYYY"
    Text,"Text",a12[50000]
}

/* Sort on Integer field descending */
sort(SourceArray, 0, "2d")

/******************************************************************************
    Example using a function in the sort() call to compare values in a row.
    Although more flexible, this option is much slower than using a sort key
    string.
******************************************************************************/

!function CompareRows(Row1, Row2) {
    return SourceArray.Integer[Row1] - SourceArray.Integer[Row2]
}

sort(SourceArray, 0, CompareRows)

Examples with !record arrays:

!record RecArray[10] {
  num,,i4
  txt,,a8
}

/* Sort record arrays (from 5-8), "num" ascending and then "txt" descending */
sort(RecArray[5], 4, "1a2d")

/* Sort record array descending+ascending */
sort(RecArray, 0, "1d2a")

/* Sorting with method in absolute values for RecArray.num */
sort(RecArray, 0, fAbsoluteComparator)

!function fAbsoluteComparator(idx1, idx2) {
  !temp val1,,i4
  !temp val2,,i4

  if (RecArray[idx1].num < 0) {
    val1 = -RecArray[idx1].num
  } else {
    val1 = RecArray[idx1].num
  }

  if (RecArray[idx2].num < 0) {
    val2 = -RecArray[idx2].num
  } else {
    val2 = RecArray[idx2].num
  }

  if (val2 = val1) {
    val1 = asc(RecArray[idx1].txt)
    val2 = asc(RecArray[idx2].txt)
  }

  return val2 - val1
}

RELATED TOPICS

Field dimensions

!record