5
$\begingroup$

I want to order some simple list of strings, such as

name = {"1.62-s", "1.6-s", "1.63-s", "1.75-s", "1.70-s"}
name//TableForm
1.62-s
1.63-s
1.6-s
1.70-s
1.75-s

However, because of the following letter "-s" I cannot order the list. Any good way to order this instead of doing by manually?

$\endgroup$
8
$\begingroup$
order = Ordering @ ToExpression[First @ StringSplit[#, "-"] & /@ name]

{2, 1, 3, 5, 4}

name[[order]]

{"1.6-s", "1.62-s", "1.63-s", "1.70-s", "1.75-s"}


EDIT: I changed StringSplit into First @ StringSplit due to important comments of george2079: (1), (2), (3) below.

$\endgroup$
  • $\begingroup$ THank you so much! I end of using your code for the project! $\endgroup$ – Saesun Kim Sep 30 '16 at 19:34
  • $\begingroup$ watch, this has the same issue I noted under Bob's answer. You are applying ToExpression to the "s", so there could be unexpected results if s is a defined symbol. ( you could do First@StringSplit[#, "-"] to fix that ) $\endgroup$ – george2079 Sep 30 '16 at 20:08
  • $\begingroup$ @george2079 Yes, now I see it. But do you have in mind any situation that this will actually fail? Nevertheless, First@stringSplit is ofc better. $\endgroup$ – corey979 Sep 30 '16 at 20:13
  • $\begingroup$ as an example do s := Pause[1] and you'll see your sort take 5 seconds. Even though that scenaro might seem unlikely its the sort of thing that's hard to track down if it causes a problem. $\endgroup$ – george2079 Sep 30 '16 at 20:25
6
$\begingroup$

this sorts by numeric value:

SortBy[name, 
 ToExpression@StringCases[#, n : NumberString ~~ ___ :> n] &]

{"1.6-s", "1.62-s", "1.63-s", "1.70-s", "1.75-s"}

note in some cases the numeric sorting is different from the string sort:

name = {"16.2-s", "1.6-s", "1.63-s", "1.75-s", "1.70-s"};
SortBy[name, StringTake[#, {1, -3}] &]

{"1.6-s", "16.2-s", "1.63-s", "1.70-s", "1.75-s"}

SortBy[name, 
 ToExpression@StringCases[#, n : NumberString ~~ ___ :> n] &]

{"1.6-s", "1.63-s", "1.70-s", "1.75-s", "16.2-s"}

$\endgroup$
  • $\begingroup$ Thank you for the code, even though I used @Corey's code, your code help me to understand more. I appreciate your answer! $\endgroup$ – Saesun Kim Sep 30 '16 at 19:38
5
$\begingroup$
SortBy[name, StringTake[#, {1, -3}] &]
$\endgroup$
  • 1
    $\begingroup$ As @george2079 points out, you may want to add ToExpression@ into the mix (before StringTake) to make the numerical sorting a little more robust. I was being lazy. $\endgroup$ – Quantum_Oli Sep 30 '16 at 17:27
  • $\begingroup$ Thank you for your fast answer! This was the what I wanted, but there were some generalized answer for any case, so I did not accept yours. However, I appreciate for your code! $\endgroup$ – Saesun Kim Sep 30 '16 at 19:40
5
$\begingroup$
name = {"1.62-s", "1.6-s", "1.63-s", "1.75-s", "1.70-s"};

SortBy[name, ToExpression]

(*  {"1.6-s", "1.62-s", "1.63-s", "1.70-s", "1.75-s"}  *)
$\endgroup$
  • $\begingroup$ watch for unexpected side effects should you happen to have a defined symbol "s" .. $\endgroup$ – george2079 Sep 30 '16 at 19:18
  • $\begingroup$ Thank you, I think your code is the neatest one, but I used @Corey code for the project. Thank you anyway :D $\endgroup$ – Saesun Kim Sep 30 '16 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.