Re: Friendly Challenge 2: sort by column
- To: mathgroup at smc.vnet.net
- Subject: [mg35067] Re: Friendly Challenge 2: sort by column
- From: gleam at flashmail.com ("Mr. Wizard")
- Date: Thu, 20 Jun 2002 23:56:17 -0400 (EDT)
- Organization: The Math Forum
- Sender: owner-wri-mathgroup at wolfram.com
MathGroup readers and challenge participants,
Now that I have let a few days go by, allowing time for those who
would choose to participate to write and post their methods, I will
share the function that I have been using.
First, for Hartmut Wolf, who wrote:
Paul,
what do you mean "handling duplicates" exactly?
Merely the behavior of the program when there are identical items in
the sort column, possibly resulting in ambiguity. In general I prefer
the Rotate solution as it more closely follows the default behavior of
Sort. Of course, this is slower however.
<snip>
ad[[Ordering[RotateLeft[ad,{0,2}]]]]//MatrixForm
And there you have it! That's all that I was after. :-)
Next, to DrBob, who wrote:
Another interpretation (the one I prefer) is to preserve preexisting
order in case of ties. That allows us to sort by one column, then by
another, and get the result we'd expect.
After some experimentation, I found that hw4 and hw5 (and hence
Ordering
itself) preserve order already, without modification.
As you will see, this is included in my function with the following
syntax:
positionSort[a, n] uses Rotate
positionSort[a, {n}] sorts by only column n, preserving other
ordering.
positionSort[a, {n, o, ...} sorts secondarily by o, etc.
n can be negative to give the column n from the end.
A third argument can be given to specify an arbitrary sort function.
Here is a variation of the function that I use. The original code
uses pattern matching differently (in place of the If statement, for
example), and is too verbose for posting, though it yields a small
improvement in performance:
Notebook[{
Cell["Array test function", "Text"],
Cell[BoxData[
\(mtest = #~TensorRank~2 > 1 &\)], "Input"],
Cell["Optional sort function handling", "Text"],
Cell[BoxData[
\(zz =
HoldPattern[
z : \(\((_Symbol | _Function | _Sequence)\) :
Sequence[]\)]\)], "Input"],
Cell["Handling of trivial parameters", "Text"],
Cell[BoxData[{
\(positionSort[a_, 0 | {0}] := a\), "\n",
\(positionSort[a_List, 1] := Sort@a\)}], "Input"],
Cell["\<\
Sort by only one column (disregard the rest); arbitrary sort function\
\
\>", "Text"],
Cell[BoxData[
\(positionSort[a_?mtest, {p_Integer} | \(p : {_Integer .. }\),
zz] := a\[LeftDoubleBracket]
a\[LeftDoubleBracket]All, p\[RightDoubleBracket]~Ordering~
z\[RightDoubleBracket]\)], "Input"],
Cell["Arbitrary sort function", "Text"],
Cell[BoxData[
\(positionSort[a_?mtest, p_Integer, zz] :=
a\[LeftDoubleBracket]a~RotateLeft~{0, If[p < 0, p, p - 1]}~
Ordering~z\[RightDoubleBracket]\)], "Input"]
}]
Paul