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$
0

4 Answers 4

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$
4
  • $\begingroup$ THank you so much! I end of using your code for the project! $\endgroup$
    – Saesun Kim
    Sep 30, 2016 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, 2016 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, 2016 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, 2016 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$
1
  • $\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, 2016 at 19:38
5
$\begingroup$
SortBy[name, StringTake[#, {1, -3}] &]
$\endgroup$
2
  • 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$ Sep 30, 2016 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, 2016 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$
2
  • $\begingroup$ watch for unexpected side effects should you happen to have a defined symbol "s" .. $\endgroup$
    – george2079
    Sep 30, 2016 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, 2016 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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