如何在ruby表中按数字顺序对文本进行排序

时间:2017-05-24 00:24:10

标签: ruby sorting

我试图用Ruby对此文本进行排序,但它不起作用。

1,fgff
12,seffdd
2,dssffs

使用:

cat sorting  | ruby -ne 'BEGIN{ $x=[]}; $x << $_.chomp.to_s; END { puts $x.sort }'

我得到了这个结果:

1,fgff
12,seffdd
2,dssffs

我期待这个

1,fgff
2,dssffs
12,seffdd

我如何修复我的代码?

2 个答案:

答案 0 :(得分:6)

问题是你没有按数字排序,你按字符值排序:

[1, 12, 2].sort # => [1, 2, 12]
%w[1 12 2].sort # => ["1", "12", "2"]

相反:

str = <<EOT
1,fgff
12,seffdd
2,dssffs
EOT

str.lines.sort_by { |l| l.to_i }.join
# => "1,fgff\n" +
#    "2,dssffs\n" +
#    "12,seffdd\n"

to_i将返回字符串的整数值,直到第一个非数字:

'1'.to_i # => 1
'1 2'.to_i # => 1
'1,2'.to_i # => 1
'1_2'.to_i # => 12

最后一个成功,因为Ruby和许多其他语言一样,允许使用下划线(_)作为分隔符,类似于我们使用逗号的方式:

1000 # => 1000
1_000 # => 1000

知道:

'1,fgff'.to_i # => 1
'12,seffdd'.to_i # => 12
'2,dssffs'.to_i # => 2

了解sortsort_by之间的区别也很有用。在正确的编程情况下,使用合适的加速器可以获得重要的加速。

答案 1 :(得分:1)

如果字符串的数字部分可能重复,并且字符串的其余部分用于断开关系,则可以执行以下操作。

str =<<END
1,fgff
12,seffdd
12,seffda
2,dssffs
END

str.lines.sort_by do |s|
  n, t = s.split(',')
  [n.to_i, t]
end
  #=> ["1,fgff\n", "2,dssffs\n", "12,seffda\n", "12,seffdd\n"]

有关如何排序数组的说明,请参阅Array#<=>