# How to pass composite function list to SortBy?

In order to sort alphanumeric-as-string data of the form {"T3", "T14", "T1", "E2"}, so that "T14" comes after "T3", SortBy requires the tiebreaker function list:

{StringTake[#, 1] &, ToExpression@StringDrop[#, 1] &}


Which works as intended when this expression is inserted literally in SortBy. However, defining a utility function

mySort[x_String]:={StringTake[x, 1] , ToExpression@StringDrop[x, 1]}

doesn't work since the output is a list of expressions rather than a list of functions.

The alternative - to define a function via

mySort := {StringTake[#, 1] &, ToExpression@StringDrop[#, 1] &}


only works when the list to be sorted is 1-dimensional (as above) but not with lists of the form data2={"T3"->a, "T14"->b, "T1"->c, "E2"->d} where it is necessary to use SortBy[data2,mySort[#[[1]]]&].

Any alternatives that will work for general expressions?

-
I edited the previous typo, but it results in "T14" before "T3". Do you have the opposite? –  alancalvitti Jun 20 '12 at 20:08
Oh, you're right. Forget my previous comment. –  Heike Jun 20 '12 at 20:09

I think this question admits an elegant solution. Here is my attempt: define a special wrapper:

ClearAll[sortFun];
sortFun /: SortBy[expr_, sortFun[funs_List, partFun_]] :=
SortBy[expr, Map[Composition[#, partFun] &, funs]];


Now,

mySort := {StringTake[#, 1] &, ToExpression@StringDrop[#, 1] &}


and

SortBy[{"T3","T14","T1","E2"}, sortFun[mySort, Identity]]

(*   {E2,T1,T3,T14}  *)


while

SortBy[{"T3"->a,"T14"->b,"T1"->c,"E2"->d}, sortFun[mySort, First]]

(*  {E2->d,T1->c,T3->a,T14->b} *)


EDIT

Perhaps more elegantly

ClearAll[sortFun];
sortFun /: SortBy[expr_, sortFun[funs_List, partFun_]] :=


and just for fun, another version:

ClearAll[sortFun];
sortFun /: call : SortBy[expr_, sortFun[funs_List, partFun_]] :=

@alancalvitti I actually don't find carrying sortFun around a big burden. It is a very general wrapper, and it minimally changes the syntax. One can use some shorter name if sortFun is too long. One could also add rules to SortBy, but I'd rather not do it. –  Leonid Shifrin Jun 20 '12 at 20:24