["2-5", "1-10", "2-1", "3-3", "1-3"].sort => ["1-10", "1-3", "2-1", "2-5", "3-3"]
そうじゃなくて、ハイフンの前の数字の昇順→ハイフンの後ろの数字の昇順で並んで欲しい。そんなときはブロック引数を使う。
["2-5", "1-10", "2-1", "3-3", "1-3"].sort { |a, b| as = a.split("-") bs = b.split("-") r = as.first.to_i - bs.first.to_i r != 0 ? r : as.last.to_i - bs.last.to_i } => ["1-3", "1-10", "2-1", "2-5", "3-3"]
また、このソートは
["2-5", "1-10", "2-1", "3-3", "1-3"].sort_by{ |i| i.split("-").map{ |e| e.to_i } }
と、sort_by を使って書ける。sort_by は配列の各要素からソート用のオブジェクトを作り、そのソート用オブジェクト同士を<=>で比較した結果で元の配列をソートするもの。
ところでRubyのリファレンスマニュアルには、sort のブロックは比較の度に呼ばれるのでブロックの処理が重いと sort が致命的に重くなるが、sort_by のブロックは要素の数しか呼ばれないので実行時間は O(n) のオーダーで済むと書かれている。
しかし、この程度のブロックの処理ならば、どちらで書いても差はない(余計な処理がないためか、むしろsortの方がわずかに速い)ので、気にせずに書きやすい方で書くのがいいと思う。この場合、コードが簡潔なsort_byの方が良い感じだが、何をやってるのか一見して分かりにくいのが欠点か。