Ruby on rails 如何使用sort_by按字母顺序排序,然后按数字排序,然后按特殊字符排序
我有一个数组:Ruby on rails 如何使用sort_by按字母顺序排序,然后按数字排序,然后按特殊字符排序,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有一个数组: arr = ["Bar", "abc", "foo", "1", "20”, "10", "_def"] 我需要先使用不区分大小写的字母顺序进行排序,然后使用特殊字符进行数字排序 我正在尝试使用排序依据: irb(main):071:0> arr.sort_by {|s| [s[/[0-9a-z]+/], s.to_i]} => [&qu
arr = ["Bar", "abc", "foo", "1", "20”, "10", "_def"]
我需要先使用不区分大小写的字母顺序进行排序,然后使用特殊字符进行数字排序
我正在尝试使用排序依据
:
irb(main):071:0> arr.sort_by {|s| [s[/[0-9a-z]+/], s.to_i]}
=> ["1", "10", "20", "abc", "Bar", "_def", "foo"]
输出必须是:
arr = ["abc", "Bar", "foo", "1", “10”, “20", "_def"]
您可以先创建组,然后对组进行排序
arr.each_with_object(Array.new(3) { Array.new }) do |word, group|
if word.match /^[A-Za-z]/
group.first
elsif word.match /^[0-9]/
group.second
else
group.third
end << word
end.flat_map{ |group| group.sort_by{ |x| x.downcase } }
#=> ["abc", "Bar", "foo", "1", "10", "20", "_def"]
arr.each_with_object(Array.new(3){Array.new})do|word,group|
如果word.match/^[A-Za-z]/
第一组
elsif word.match/^[0-9]/
第二组
其他的
第三组
结束[“abc”、“Bar”、“foo”、“1”、“10”、“20”、“_def”]
来自:
数组以“按元素”的方式进行比较;使用
运算符将元的第一个元素与其他元的第一个元素进行比较,然后对每个第二个元素进行比较,以此类推
您可以通过创建排序组来利用此行为:
arr = ["Bar", "abc", "foo", "1", "20", "10", "_def"]
arr.sort_by do |s|
case s
when /^[a-z]/i
[1, s.downcase]
when /^\d/
[2, s.to_i]
else
[3, s]
end
end
#=> ["abc", "Bar", "foo", "1", "10", "20", "_def"]
第一个元素(1
,2
,3
)定义组的位置:第一个位置有字母的字符串,第二个位置有数字字符串,其余位置在第三个位置。在每个组中,元素按第二个元素排序:带字母的字符串按其小写值排序,数字字符串按其整数值排序,其余的按其自身排序。需要一点基准:
require 'active_support/core_ext/array/access.rb'
require 'fruity'
ARR = ["Bar", "abc", "foo", "1", "20", "10", "_def"]
def run_demir(ary)
ary.each_with_object(Array.new(3) { Array.new }) do |word, group|
if word.match /^[A-Za-z]/
group.first
elsif word.match /^[0-9]/
group.second
else
group.third
end << word
end.flat_map{ |group| group.sort_by{ |x| x.downcase } }
end
def run_stefan(ary)
ary.sort_by do |s|
case s
when /^[a-z]/i
[1, s.downcase]
when /^\d/
[2, s.to_i]
else
[3, s]
end
end
end
run_demir(ARR) # => ["abc", "Bar", "foo", "1", "10", "20", "_def"]
run_stefan(ARR) # => ["abc", "Bar", "foo", "1", "10", "20", "_def"]
compare do
demir { run_demir(ARR) }
Stefan { run_stefan(ARR) }
end
刚刚意识到这是一个变体。也许它提供了一些额外的信息。很好的解决方案Stefan。它不是真正的变体,它是一种替代方法。做某些事情的方法有限,因此经常会有重叠。就我个人而言,我觉得这更简单,更容易阅读,而且应该更快。哦我感觉到一个基准即将到来。这不能正确地对字符串排序,例如'aa'
与'a1'
,因为您只在第一个字符上决定“组”。如果我正确理解OP,他希望有一个字符的“自定义排序序列”,首先是所有字母,然后是所有数字,最后是所有其他字符。(@user3189916:你能确认一下吗?)。数组是否有方法名second
和third
?你用的是哪个Ruby版本?@Rajagopalan不,它们不是Ruby方法。我使用这些方法是因为这个问题有ruby-on-rails-5标记。对于普通ruby,可以使用组[1]和组[2]来代替这些方法。我知道第[1]组和第[2]组可以被使用,而不是分发代码,还可以解释它是如何工作的以及为什么它是合适的解决方案。我们的目标是教育,而不仅仅是解决眼前的问题;我们可以控制我们的输入。这让我觉得这是一个家庭作业问题。""
# >> Running each test 512 times. Test will take about 1 second.
# >> Stefan is faster than demir by 2x ± 0.1