I'm having a bit of trouble figuring out the right Sort
syntax to use on a list of lists. Consider the following list:
list=
{
{"B0T", "Ch72", "T0p36K", "Vdiv2047p92", "Vg75V"},
{"B0T", "Ch70", "T0p28K", "Vdiv2047p92", "Vg65V"},
{"B0T", "Ch70", "T0p28K", "Vdiv2047p92", "Vg60V"},
{"B0T", "Ch72", "T0p36K", "Vdiv2047p92", "Vg70V"}
}
I would like the resulting list to have the following:
- Order first by anything looking like "T[0-9p]+K" (regex), and rearrange to have this value be first
- Then order by "Vg[0-9p]+V", and rearrange to have it be 2nd.
- Then order by "Ch[0-9]+", and rearrange to 3rd,
- Then order the rest in alphabetical order, and rearrange
So, the final outcome would be:
{
{"T0p28K", "Vg60V", "Ch70", "B0T", "Vdiv2047p92"},
{"T0p28K", "Vg65V", "Ch70", "B0T", "Vdiv2047p92"},
{"T0p36K", "Vg70V", "Ch72", "B0T", "Vdiv2047p92"},
{"T0p36K", "Vg75V", "Ch72", "B0T", "Vdiv2047p92"}
}
Note: while it looks like all of the columns would be the same at the beginning, they might not always have the same position, and the number of columns themselves might change.
FWIW, eventually I will be separating the strings above with:
valRegExp =
RegularExpression[
"(Vdiv|T|Vbias|Vg|B|Ch)([Ss][Ww]|[\-0-9p]+)(K|V|T)?"];
Map[Flatten[StringCases[#,
valRegExp :> {"$1", StringReplace["$2", "p" -> "."],
"($3)"}], {2}][[1]] &, list]
Is there a way to sort them "in place"? Is this better approached as a two step function: first sort, then rearrange?
EDIT Heike's answer along with a call to
Clear[SortByColumn]
SortByColumn::usage =
"SortByColumn[List,Column,Direction]: Returns the list sorted by \
'Column' in either ascending (Direction= \"asc\") or descending \
(Direction = \"desc\") order. Default is in ascending order. For \
sorting more than one column, input Column as a list. For example, \
Column={1,2} will sort first on Column 1, then on Column 2.";
SortByColumn[list_List, col_, dir_String: "asc"] :=
Which[dir == "desc",
Sort[list, ! OrderedQ[{#1[[col]], #2[[col]]}] &], dir == "asc",
Sort[list, OrderedQ[{#1[[col]], #2[[col]]}] &]]
Actually solves my problem, I think.