Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何使用sort_by按字母顺序排序,然后按数字排序,然后按特殊字符排序_Ruby On Rails_Ruby - Fatal编程技术网

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