Well, there is no builtin, off the shelf, functionality in ED that does this, but you can easily make your own method. Here is the code. The function takes 3 to 4 parameters. The parameters are:
e1: atom contaning the table
e2: the column that
e3: boolean: 1 if ascending, 0 if descending
e4: number of fixed columns that the table contains
QuickSortTable(e1, e2, e3, {e4})
Code: Select all
do(
var([atmTable], vbAtom, p(1)),
var([valSortColumn], vbValue, p(2)),
var([valAscending], vbValue, p(3)),
var([valSortFixedColumn], vbValue, p(4)),
var([atmIndexArray], vbAtom),
var([atmDummyTable], vbAtom),
var([valColumn], vbValue),
if(
nRows(atmTable) <= 1,
return
),
{**Create indexed value**}
atmIndexArray := Array_Create(Model, [IndexArray]),
atmDummyTable := Array_Create(Model, [DummyArray]),
Array_SetSize(atmIndexArray, nRows(atmTable)),
Array_SetSize(atmDummyTable, nRows(atmTable)),
Repeat(
Array_GetSize(atmIndexArray),
Array_Set(atmIndexArray, Count, Count)
),
QuickSortIndexed(atmTable, valSortColumn, atmIndexArray, valAscending),
Repeat(
nCols(atmTable) + valSortFixedColumn,
do(
valColumn := Count - valSortFixedColumn,
{**Save the array in column count**}
Repeat(
nRows(atmTable),
Cell(Count, 1, atmDummyTable) := Cell(Count, valColumn, atmTable)
),
{**Copy it back in rearranged order**}
Repeat(
nRows(atmTable),
Cell(Count, valColumn, atmTable) := Cell(Cell(Count, 1, atmIndexArray), 1, atmDummyTable)
)
)
),
DestroyAtom(atmIndexArray),
DestroyAtom(atmDummyTable)
)
QuickSortIndexed(e1, e2, e3, e4)
where
e1: atom contaning the table
e2: the column that
e3: temporary atom where the sorted table is first placed
e4: boolean: 1 if ascending, 0 if descending
Code: Select all
do(
var([atmTable], vbAtom, p(1)),
var([valSortColumn], vbValue, p(2)),
var([atmIndexArray], vbAtom, p(3)),
var([valAscending], vbValue, p(4)),
var([valContinue], vbValue, True),
var([valM], vbValue, 7),
var([valJStack], vbValue, 0),
var([valA], vbValue),
var([valI], vbValue),
var([valJ], vbValue),
var([valL], vbValue, 1),
var([valIR], vbValue, nRows(atmTable)),
var([valBreak], vbValue),
var([valK], vbValue),
var([valIndext], vbValue),
if(
valAscending,
{**Sort ascending**}
While(
valContinue,
if(
valIR - valL < valM,
do(
For(
valJ := valL + 1,
valJ <= valIR,
inc(valJ),
do(
valIndext := Cell(valJ, 1, atmIndexArray),
valA := Cell(valIndexT, valSortColumn, atmTable),
valBreak := False,
for(
valI := valJ - 1,
and(
valI >= valL,
valBreak = False
),
dec(valI),
if(
Cell(Cell(valI, 1, atmIndexArray), valSortColumn, atmTable) <= valA,
do(
inc(valI),
valBreak := True
),
Cell(valI + 1, 1, atmIndexArray) := Cell(valI, 1, atmIndexArray)
)
),
Cell(valI + 1, 1, atmIndexArray) := valIndexT
)
),
if(
valJStack = 0,
valContinue := False,
do(
valIR := PopValue,
valL := PopValue,
dec(valJstack, 2)
)
)
),
do(
valK := Trunc((valL + valIR) / 2), {**Trunc(x/2) is Equal to bitwise left shift with 1**}
{**Swap row k and l + 1**}
PushValue(Cell(valK, 1, atmIndexArray)),
Cell(valK, 1, atmIndexArray) := Cell(valL + 1, 1, atmIndexArray),
Cell(valL + 1, 1, atmIndexArray) := PopValue,
if(
Cell(Cell(valL, 1, atmIndexArray), valSortColumn, atmTable) > Cell(Cell(valIR, 1, atmIndexArray), valSortColumn, atmTable),
{**Swap row l and ir**}
do(
PushValue(Cell(valL, 1, atmIndexArray)),
Cell(valL, 1, atmIndexArray) := Cell(valIR, 1, atmIndexArray),
Cell(valIR, 1, atmIndexArray) := PopValue
)
),
if(
Cell(Cell(valL + 1, 1, atmIndexArray), valSortColumn, atmTable) > Cell(Cell(valIR, 1, atmIndexArray), valSortColumn, atmTable),
{**Swap row l + 1 and ir**}
do(
PushValue(Cell(valL + 1, 1, atmIndexArray)),
Cell(valL + 1, 1, atmIndexArray) := Cell(valIR, 1, atmIndexArray),
Cell(valIR, 1, atmIndexArray) := PopValue
)
),
if(
Cell(Cell(valL, 1, atmIndexArray), valSortColumn, atmTable) > Cell(Cell(valL + 1, 1, atmIndexArray), valSortColumn, atmTable),
{**Swap row l and l + 1**}
do(
PushValue(Cell(valL, 1, atmIndexArray)),
Cell(valL, 1, atmIndexArray) := Cell(valL + 1, 1, atmIndexArray),
Cell(valL + 1, 1, atmIndexArray) := PopValue
)
),
valI := valL + 1,
valJ := valIR,
valIndexT := Cell(valL + 1, 1, atmIndexArray),
valA := Cell(valIndexT, valSortColumn, atmTable),
{**Beginning of innermost loop**}
valBreak := False,
LoopUntil(
valBreak = True,
do(
{**Scan up to find element > a**}
inc(valI),
While(
and(
Cell(Cell(valI, 1, atmIndexArray), valSortColumn, atmTable) < valA,
valI <= nRows(atmTable)
),
inc(valI)
),
{**Scan down to find element < a**}
dec(valJ),
While(
and(
Cell(Cell(valJ, 1, atmIndexArray), valSortColumn, atmTable) > valA,
valJ > 0
),
dec(valJ)
),
if(
valJ < valI,
valBreak := True,
{**Swap row i and j**}
do(
PushValue(Cell(valI, 1, atmIndexArray)),
Cell(valI, 1, atmIndexArray) := Cell(valJ, 1, atmIndexArray),
Cell(valJ, 1, atmIndexArray) := PopValue
)
)
)
),
Cell(valL + 1, 1, atmIndexArray) := Cell(valJ, 1, atmIndexArray),
Cell(valJ, 1, atmIndexArray) := valIndexT,
inc(valJstack, 2),
{**Push pointers to larger subarray on stack, process smaller subarray immediately**}
if(
valIR - valI + 1 >= valJ - 1,
do(
PushValue(valI),
PushValue(valIR),
valIR := valJ - 1
),
do(
PushValue(valL),
PushValue(valJ - 1),
valL := valI
)
)
)
)
),
{**Sort Descending**}
While(
valContinue,
if(
valIR - valL < valM,
do(
For(
valJ := valL + 1,
valJ <= valIR,
inc(valJ),
do(
valIndext := Cell(valJ, 1, atmIndexArray),
valA := Cell(valIndext, valSortColumn, atmTable),
valBreak := False,
for(
valI := valJ - 1,
and(
valI >= valL,
valBreak = False
),
dec(valI),
if(
Cell(Cell(valI, 1, atmIndexArray), valSortColumn, atmTable) >= valA,
do(
inc(valI),
valBreak := True
),
Cell(valI + 1, 1, atmIndexArray) := Cell(valI, 1, atmIndexArray)
)
),
Cell(valI + 1, 1, atmIndexArray) := valIndexT
)
),
if(
valJStack = 0,
valContinue := False,
do(
valIR := PopValue,
valL := PopValue,
dec(valJstack, 2)
)
)
),
do(
valK := Trunc((valL + valIR) / 2), {**Trunc(x/2) is Equal to bitwise left shift with 1**}
{**Swap row k and l + 1**}
PushValue(Cell(valK, 1, atmIndexArray)),
Cell(valK, 1, atmIndexArray) := Cell(valL + 1, 1, atmIndexArray),
Cell(valL + 1, 1, atmIndexArray) := PopValue,
if(
Cell(Cell(valL, 1, atmIndexArray), valSortColumn, atmTable) < Cell(Cell(valIR, 1, atmIndexArray), valSortColumn, atmTable),
{**Swap row l and ir**}
do(
PushValue(Cell(valL, 1, atmIndexArray)),
Cell(valL, 1, atmIndexArray) := Cell(valIR, 1, atmIndexArray),
Cell(valIR, 1, atmIndexArray) := PopValue
)
),
if(
Cell(Cell(valL + 1, 1, atmIndexArray), valSortColumn, atmTable) < Cell(Cell(valIR, 1, atmIndexArray), valSortColumn, atmTable),
{**Swap row l + 1 and ir**}
do(
PushValue(Cell(valL + 1, 1, atmIndexArray)),
Cell(valL + 1, 1, atmIndexArray) := Cell(valIR, 1, atmIndexArray),
Cell(valIR, 1, atmIndexArray) := PopValue
)
),
if(
Cell(Cell(valL, 1, atmIndexArray), valSortColumn, atmTable) < Cell(Cell(valL + 1, 1, atmIndexArray), valSortColumn, atmTable),
{**Swap row l and l + 1**}
do(
PushValue(Cell(valL, 1, atmIndexArray)),
Cell(valL, 1, atmIndexArray) := Cell(valL + 1, 1, atmIndexArray),
Cell(valL + 1, 1, atmIndexArray) := PopValue
)
),
valI := valL + 1,
valJ := valIR,
valIndexT := Cell(valL + 1, 1, atmIndexArray),
valA := Cell(valIndexT, valSortColumn, atmTable),
{**Beginning of innermost loop**}
valBreak := False,
LoopUntil(
valBreak = True,
do(
{**Scan up to find element > a**}
inc(valI),
While(
and(
Cell(Cell(valI, 1, atmIndexArray), valSortColumn, atmTable) > valA,
valI <= nRows(atmTable)
),
inc(valI)
),
{**Scan down to find element < a**}
dec(valJ),
While(
and(
Cell(Cell(valJ, 1, atmIndexArray), valSortColumn, atmTable) < valA,
valJ > 0
),
dec(valJ)
),
if(
valJ < valI,
valBreak := True,
{**Swap row i and j**}
do(
PushValue(Cell(valI, 1, atmIndexArray)),
Cell(valI, 1, atmIndexArray) := Cell(valJ, 1, atmIndexArray),
Cell(valJ, 1, atmIndexArray) := PopValue
)
)
)
),
Cell(valL + 1, 1, atmIndexArray) := Cell(valJ, 1, atmIndexArray),
Cell(valJ, 1, atmIndexArray) := valIndexT,
inc(valJstack, 2),
{**Push pointers to larger subarray on stack, process smaller subarray immediately**}
if(
valIR - valI + 1 >= valJ - 1,
do(
PushValue(valI),
PushValue(valIR),
valIR := valJ - 1
),
do(
PushValue(valL),
PushValue(valJ - 1),
valL := valI
)
)
)
)
)
)
)