ProblemYou have data in one or more lists or matrix vectors that you need to sort.
SolutionUse Sort List() or Sort List Into(), Rank(), or put the lists and vectors in a data table and sort it.
names = {"fred", "Andy", "Rory", "bess", "susy", "perl"};
sname = Sort List( names );
Show( names, sname );
names = {"fred", "Andy", "Rory", "bess", "susy", "perl"}; // unchanged
sname = {"Andy", "bess", "fred", "perl", "Rory", "susy"}; // sorted
names = {"fred", "Andy", "Rory", "bess", "susy", "perl"};
Sort List Into( names );
Show( names );
names = {"Andy", "bess", "fred", "perl", "Rory", "susy"}; // sorted in-placeBoth examples above operate on a single list. If there is a second list of phone numbers, they don't stick to the names.
To make several lists all have the same sort, you might use the Rank() function. The lists should have the same number of elements and no missing values in the sort-key list.
names = {"fred", "Andy", "Rory", "bess", "susy", "perl"};
phone = {"x321", "x322", "x323", "x324", "x325", "x326"};
rooms = {"1003", "1001", "1005", "1002", "1006", "1004"};
rnk = Rank( names );
snames = names[rnk];
sphone = phone[rnk];
srooms = rooms[rnk];
Show( snames, sphone, srooms );
snames = {"Andy", "bess", "fred", "perl", "Rory", "susy"};sphone = {"x322", "x324", "x321", "x326", "x323", "x325"};srooms = {"1001", "1002", "1003", "1004", "1005", "1006"};
Above, the new lists with the prefix s are all sorted by name.
If you have multiple lists, of the same length, but paired across the lists, perhaps a data table would be a better data structure. You might find it easier to use a table because you can see it, save it, subset it, ... But if you have the lists already, you can build a table from them. Here is a re-usable user function that does that:
zip = Function( {variableNameList},
{iVarName, dt, data},
dt = New Table( "zip", "invisible" );
For( iVarName = 1, iVarName <= N Items( variableNameList ), iVarName += 1,
data = Eval( variableNameList[iVarName] );
If( Is Matrix( data ) | Is Number( data[1] ),
dt << New Column( Char( variableNameList[iVarName] ), "numeric", values( data ),
setProperty( "wasMatrix", eval(Is Matrix( data ) ) ) )
,
dt << New Column( Char( variableNameList[iVarName] ), "character", values( data ),
setProperty( "wasString", eval( Is String( data[1] ) ) ) )
);
);
dt << New Column( "_original order_", values( 1 :: N Rows( dt ) ) );
dt << setdirty( 0 );
dt;
);
example:
cars = {chevy, volkswagon, honda, ford, toyota};
doors = [4, 2, 2, 5, 2];
miles = {30000, 20000, 40000, 10000, 50000};
owner = {"fred", "susan", "ralph", "penelope", "terry"};
zippedDt = zip( {cars, doors, miles, owner} );
zippedDt << sort( by( miles ), replacetable( 1 ) );
zippedDt << show Window;
Lists are in table's columns, sorted by milesIf you are working with lists, you might want all the lists back again. Here's an unzip function:
unzip = Function( {dt},
{result, cols, iCol, col, names, iRow},
cols = dt << getcolumnnames;
result = {};
For( iCol = 1, iCol < N Items( cols ), iCol += 1,
col = Column( dt, cols[icol] );
If( col << getdatatype( "English" ) == "Numeric",
If( col << getproperty( "wasMatrix" ),
Insert Into( result, col << getValues );
,
result[N Items( result ) + 1] = As List( dt[0, iCol] )
)
,
If( col << getproperty( "wasString" ),
result[N Items( result ) + 1] = (dt[0, iCol])
,
result[N Items( result ) + 1] = As Name( dt[0, iCol] )
)
);
);
result;
);
example:
{cars, doors, miles, owner} = unzip( zippedDt );
List( 4 elements ) assigned.
cars:{ford, volkswagon, chevy, honda, toyota}
doors:[5, 2, 4, 2, 2]
miles:{10000, 20000, 30000, 40000, 50000}
owner:{"penelope", "susan", "fred", "ralph", "terry"}
Finally
Close( zippedDt, nosave );
DiscussionBe sure to clean up the invisible table if you use the zip/unzip functions. (They are unrelated to the compression function for .zip files. JMP has support for that in the zip archive object.)
The data table is a great tool for complicated data structures. You can make hidden or private tables for managing data without using the wrapper functions above. Lists may be more efficient than data tables if you need to add and remove a lot of items (queues and stacks might be slow if implemented as adding and removing rows from a table.) The zip function (above) expects a list of names. A name (no quotation marks) is not the same as a string (uses quotation marks). Passing a list of names reduces the number of times data is copied.
See Alsohttps://www.jmp.com/support/help/14-2/list-functions.shtml