问题描述
我有一个数组young = (input() == 'True')
famous = (input() == 'True')
if young=='True' and famous=='True':
print('You must be rich!')
else:
print('There is always the lottery...')
。排序后,得到以下结果:
["Q10","Q100","Q1000","Q1000a","Q1001","Q98"]
由于这种行为,我不能正确地排序我的ActiveRecord对象。我有一个['Q100','Q1000','Q1000a','Q98','Q10','Q1001'].sort
["Q10","Q98"]
模型,其中有一个字段Question
。我需要根据标签对它进行排序。因此,带有标签label
的问题将是第一个,带有标签Q1
的问题将是第一个,依此类推。我得到与上述数组示例所述的ActiveRecord相似的顺序。我正在使用postgresql作为数据库。
现在我有3个问题。
- 为什么字母数字字符串排序会那样?
- 如何在不使用排序块的情况下实现所需的排序?
- 如何在ActiveRecord中实现这种排序?
解决方法
如果您的数组是
arr = ["Q10","Q100","Q1000","Q8","Q1001","Q98"]
你可以写
arr.sort_by { |s| s[/\d+/].to_i }
#=> ["Q8","Q10","Q98","Q1001"]
如果
s = "Q1000"
然后
s[/\d+/].to_i
#=> 1000
请参见Enumerable#sort_by和String#[]。
正则表达式/\d+/
与包含一个或多个数字的s
子字符串匹配。
如果数组是
arr = ["Q10b","Q10a","Q10c"]
你可以写
arr.sort_by { |s| [s[/\d+/].to_i,s[/\D+\z/]] }
#=> ["Q10a","Q10b","Q10c","Q1001"]
如果
s = "Q10b"
然后
[s[/\d+/].to_i,s[/\D+\z/]]
#=> [10,"b"]
正则表达式/\D+\z/
与s
的子字符串匹配,该子字符串在字符串的末尾(\z
)包含一个或多个非数字。
请参阅Array#<=>,特别是第三段,以获取有关排序时如何对数组进行排序的说明。
如果数组是
arr = ["Q10b","P100","PQ10a","Q10c"]
你可以写
arr.sort_by { |s| [s[/\A\D+/],s[/\d+/].to_i,s[/\D+\z/]] }
#=> ["P100","Q1001"]
如果
s = "PQ10a"
然后
[s[/\A\D+/],s[/\D+\z/]]
#=> ["PQ",10,"a"]
正则表达式/\A\D+/
与s
的子字符串匹配,该子字符串在字符串的开头(\A
)包含一个或多个非数字。
这应该为您解决问题,在排序之前将其转换为数字。
['100','1000','98','10','1001'].map(&:to_i).sort
这个奇怪的map(&:to_i)
是map { |x| x.to_i }
的简写
编辑:
您可以使用AR执行此操作。如果该列不包含伪装成字符串的数字,则会抛出错误。
Model.order("some_column::integer")
编辑II:
如果它也包含字符串,请尝试。
Model.order("cast(some_column as integer))"