Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.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 将字符串排序在数字之前_Ruby On Rails_Ruby_Sorting - Fatal编程技术网

Ruby on rails 将字符串排序在数字之前

Ruby on rails 将字符串排序在数字之前,ruby-on-rails,ruby,sorting,Ruby On Rails,Ruby,Sorting,为了确定范围,我正在寻找一种不同寻常的排序机制。 假设我们有以下数组: arr = ["33", "a30", "b333", "44", "22", "a15"] 如何对其排序,使非数字字符串在数字字符串之前排序? 这是我希望达到的结果 sorted_arr = ["a15", "a30", "b333", "22", "33", "44"] 我尝试了各种组合的sort\u by和sort,但我还没有实现正确的排序。。。因此,任何帮助都将不胜感激。谢谢 PS:我知道我写过“用于范围界定”,

为了确定范围,我正在寻找一种不同寻常的排序机制。
假设我们有以下数组:

arr = ["33", "a30", "b333", "44", "22", "a15"]
如何对其排序,使非数字字符串在数字字符串之前排序?
这是我希望达到的结果

sorted_arr = ["a15", "a30", "b333", "22", "33", "44"]
我尝试了各种组合的
sort\u by
sort
,但我还没有实现正确的排序。。。因此,任何帮助都将不胜感激。谢谢


PS:我知道我写过“用于范围界定”,但答案不一定是用于
default\u范围
块。一旦我找到了正确的排序技术,我将稍后尝试调整它。

这不是最优雅的解决方案,但一种方法是创建两个数组,一个数组包含所有以非数字开头的元素,另一个数组包含所有以数字开头的元素。对两个数组进行排序,然后将数组连接起来这不是最优雅的解决方案,但其中一种方法是创建两个数组,一个数组包含以非数字项开头的所有元素,另一个数组包含以数字项开头的所有元素。对两个数组进行排序,然后将数组连接起来。您可以执行以下操作:

arr.sort_by{|e| [e =~ /\A\d/ ? 1 : 0, e.your_original_sort_condition]}
arr.sort.partition { |x| x[/^[^\d]/] }.inject(:+)
#  => ["a15", "a30", "b333", "22", "33", "44"] 
这将对数组进行排序,然后对所有不以数字开头的元素以及所有以数字开头的元素进行分组:

arr.sort.partition { |x| x[/^[^\d]/] }
# => [["a15", "a30", "b333"], ["22", "33", "44"]]
然后将两个阵列连接在一起。

您可以执行以下操作:

arr.sort.partition { |x| x[/^[^\d]/] }.inject(:+)
#  => ["a15", "a30", "b333", "22", "33", "44"] 
这将对数组进行排序,然后对所有不以数字开头的元素以及所有以数字开头的元素进行分组:

arr.sort.partition { |x| x[/^[^\d]/] }
# => [["a15", "a30", "b333"], ["22", "33", "44"]]

然后它将两个数组连接在一起。

还有另一种方法

代码

def sort_em(arr)
  a = arr.sort
  return a if a.first =~ /\D/ || a.last !~ /\D/  
  a.rotate(a.index(a.find { |e| e =~ /\D/ }))
end
arr = ["33", "a30", "b333", "44", "22", "a15"]
sort_em(arr)
  #=> ["a15", "a30", "b333", "22", "33", "44"]
示例

def sort_em(arr)
  a = arr.sort
  return a if a.first =~ /\D/ || a.last !~ /\D/  
  a.rotate(a.index(a.find { |e| e =~ /\D/ }))
end
arr = ["33", "a30", "b333", "44", "22", "a15"]
sort_em(arr)
  #=> ["a15", "a30", "b333", "22", "33", "44"]
注释

require 'benchmark'

n = 10 # Example
arr = (Array.new(n) {rand(n).to_s } +
       Array.new(n) { (97+rand(26)).chr + rand(n).to_s }).shuffle
  #=> ["9", "5", "a4", "u6", "u3", "g6", "5", "l0", "9", "9",
  #    "3", "8", "t1", "3", "o5", "l6", "3", "i6", "l1", "0"]

n = 200_000
arr = (Array.new(n) {rand(n).to_s } +
       Array.new(n) { (97+rand(26)).chr + rand(n).to_s }).shuffle

def sawa(arr)  arr.sort_by{ |e| [e =~ /\A\d/ ? 1 : 0, e] } end
def darse(arr) arr.partition { |x| x =~ /\D/ }.flat_map(&:sort) end    
def uri(arr)   arr.sort.partition { |x| x[/^[^\d]/] }.inject(:+) end
def cary(arr)
  a = arr.sort
  return a if a.first =~ /\D/ || a.last !~ /\D/  
  a.rotate(a.index(a.find { |e| e =~ /\D/ }))
end

Benchmark.bm(12) do |bm|
  bm.report('@sawa'     ) { sawa(arr)  }
  bm.report('@theDarse' ) { darse(arr) }
  bm.report('@UriAgassi') { uri(arr)   }
  bm.report('@Cary'     ) { cary(arr)  }
end
                   user     system      total        real
@sawa          3.340000   0.020000   3.360000 (  3.364740)
@theDarse      0.530000   0.020000   0.550000 (  0.547846)
@UriAgassi     0.700000   0.010000   0.710000 (  0.711513)
@Cary          0.430000   0.010000   0.440000 (  0.438975)
  • 如果在分隔数字和非数字条目之前,您执行一些混合数字和非数字条目的专门的
    排序
    ,则这将不起作用
  • 如果可能存在
    “1”
    “1”
    ,并将其视为“数字”,则在
    =~
    =~
    之前添加
    .strip
  • 如果
    arr
    为空,
    [].first=~/^\d+$/#=>nil
先生们,启动引擎

require 'benchmark'

n = 10 # Example
arr = (Array.new(n) {rand(n).to_s } +
       Array.new(n) { (97+rand(26)).chr + rand(n).to_s }).shuffle
  #=> ["9", "5", "a4", "u6", "u3", "g6", "5", "l0", "9", "9",
  #    "3", "8", "t1", "3", "o5", "l6", "3", "i6", "l1", "0"]

n = 200_000
arr = (Array.new(n) {rand(n).to_s } +
       Array.new(n) { (97+rand(26)).chr + rand(n).to_s }).shuffle

def sawa(arr)  arr.sort_by{ |e| [e =~ /\A\d/ ? 1 : 0, e] } end
def darse(arr) arr.partition { |x| x =~ /\D/ }.flat_map(&:sort) end    
def uri(arr)   arr.sort.partition { |x| x[/^[^\d]/] }.inject(:+) end
def cary(arr)
  a = arr.sort
  return a if a.first =~ /\D/ || a.last !~ /\D/  
  a.rotate(a.index(a.find { |e| e =~ /\D/ }))
end

Benchmark.bm(12) do |bm|
  bm.report('@sawa'     ) { sawa(arr)  }
  bm.report('@theDarse' ) { darse(arr) }
  bm.report('@UriAgassi') { uri(arr)   }
  bm.report('@Cary'     ) { cary(arr)  }
end
                   user     system      total        real
@sawa          3.340000   0.020000   3.360000 (  3.364740)
@theDarse      0.530000   0.020000   0.550000 (  0.547846)
@UriAgassi     0.700000   0.010000   0.710000 (  0.711513)
@Cary          0.430000   0.010000   0.440000 (  0.438975)

诚然,这是一个非常有限的基准。

这里有另一种方法

代码

def sort_em(arr)
  a = arr.sort
  return a if a.first =~ /\D/ || a.last !~ /\D/  
  a.rotate(a.index(a.find { |e| e =~ /\D/ }))
end
arr = ["33", "a30", "b333", "44", "22", "a15"]
sort_em(arr)
  #=> ["a15", "a30", "b333", "22", "33", "44"]
示例

def sort_em(arr)
  a = arr.sort
  return a if a.first =~ /\D/ || a.last !~ /\D/  
  a.rotate(a.index(a.find { |e| e =~ /\D/ }))
end
arr = ["33", "a30", "b333", "44", "22", "a15"]
sort_em(arr)
  #=> ["a15", "a30", "b333", "22", "33", "44"]
注释

require 'benchmark'

n = 10 # Example
arr = (Array.new(n) {rand(n).to_s } +
       Array.new(n) { (97+rand(26)).chr + rand(n).to_s }).shuffle
  #=> ["9", "5", "a4", "u6", "u3", "g6", "5", "l0", "9", "9",
  #    "3", "8", "t1", "3", "o5", "l6", "3", "i6", "l1", "0"]

n = 200_000
arr = (Array.new(n) {rand(n).to_s } +
       Array.new(n) { (97+rand(26)).chr + rand(n).to_s }).shuffle

def sawa(arr)  arr.sort_by{ |e| [e =~ /\A\d/ ? 1 : 0, e] } end
def darse(arr) arr.partition { |x| x =~ /\D/ }.flat_map(&:sort) end    
def uri(arr)   arr.sort.partition { |x| x[/^[^\d]/] }.inject(:+) end
def cary(arr)
  a = arr.sort
  return a if a.first =~ /\D/ || a.last !~ /\D/  
  a.rotate(a.index(a.find { |e| e =~ /\D/ }))
end

Benchmark.bm(12) do |bm|
  bm.report('@sawa'     ) { sawa(arr)  }
  bm.report('@theDarse' ) { darse(arr) }
  bm.report('@UriAgassi') { uri(arr)   }
  bm.report('@Cary'     ) { cary(arr)  }
end
                   user     system      total        real
@sawa          3.340000   0.020000   3.360000 (  3.364740)
@theDarse      0.530000   0.020000   0.550000 (  0.547846)
@UriAgassi     0.700000   0.010000   0.710000 (  0.711513)
@Cary          0.430000   0.010000   0.440000 (  0.438975)
  • 如果在分隔数字和非数字条目之前,您执行一些混合数字和非数字条目的专门的
    排序
    ,则这将不起作用
  • 如果可能存在
    “1”
    “1”
    ,并将其视为“数字”,则在
    =~
    =~
    之前添加
    .strip
  • 如果
    arr
    为空,
    [].first=~/^\d+$/#=>nil
先生们,启动引擎

require 'benchmark'

n = 10 # Example
arr = (Array.new(n) {rand(n).to_s } +
       Array.new(n) { (97+rand(26)).chr + rand(n).to_s }).shuffle
  #=> ["9", "5", "a4", "u6", "u3", "g6", "5", "l0", "9", "9",
  #    "3", "8", "t1", "3", "o5", "l6", "3", "i6", "l1", "0"]

n = 200_000
arr = (Array.new(n) {rand(n).to_s } +
       Array.new(n) { (97+rand(26)).chr + rand(n).to_s }).shuffle

def sawa(arr)  arr.sort_by{ |e| [e =~ /\A\d/ ? 1 : 0, e] } end
def darse(arr) arr.partition { |x| x =~ /\D/ }.flat_map(&:sort) end    
def uri(arr)   arr.sort.partition { |x| x[/^[^\d]/] }.inject(:+) end
def cary(arr)
  a = arr.sort
  return a if a.first =~ /\D/ || a.last !~ /\D/  
  a.rotate(a.index(a.find { |e| e =~ /\D/ }))
end

Benchmark.bm(12) do |bm|
  bm.report('@sawa'     ) { sawa(arr)  }
  bm.report('@theDarse' ) { darse(arr) }
  bm.report('@UriAgassi') { uri(arr)   }
  bm.report('@Cary'     ) { cary(arr)  }
end
                   user     system      total        real
@sawa          3.340000   0.020000   3.360000 (  3.364740)
@theDarse      0.530000   0.020000   0.550000 (  0.547846)
@UriAgassi     0.700000   0.010000   0.710000 (  0.711513)
@Cary          0.430000   0.010000   0.440000 (  0.438975)


诚然,这是一个非常有限的基准。

一个值有可能包含多个字母字符吗?如果是这样,数组
[“aa7”,“b1”]
是否按您的需要排序?是的,它可以是任意字符串@wiczWhy
ruby-on-rails
标记?有些人,比如我,经常过滤Rails问题。我看到你的问题只是偶然的。我们不应该忽略相关的标签,但也不应该包含多余的标签。@CarySwoveland您仔细阅读了吗?主要部分是ruby,但它有一个rails投影。ruby,恐怕我对rails的了解还不够,不知道什么是“rails投影”:-)也许我的评论很幼稚,但我注意到所有的答案都是纯红宝石的。不过,我的观点是,如果任何标记都不是必需的,您可能会不必要地错过好的答案。一个值是否可能有多个字母字符?如果是这样,数组
[“aa7”,“b1”]
是否按您的需要排序?是的,它可以是任意字符串@wiczWhy
ruby-on-rails
标记?有些人,比如我,经常过滤Rails问题。我看到你的问题只是偶然的。我们不应该忽略相关的标签,但也不应该包含多余的标签。@CarySwoveland您仔细阅读了吗?主要部分是ruby,但它有一个rails投影。ruby,恐怕我对rails的了解还不够,不知道什么是“rails投影”:-)也许我的评论很幼稚,但我注意到所有的答案都是纯红宝石的。不过,我的观点是,如果任何标记都不是必需的,您可能会不必要地错过好的答案。对不起,
My_original_sort_condition
?因为可以使用任何字符串,只有完整的数字必须匹配,因此我将使用:
arr.sort_by{e=~/\A\d+\z/?1:0,e]
如果
“0a”
被视为“非数字字符串”,可能是
e.strip=~/\D/?0:1
?对不起,如果
“0a”
被视为“非数字字符串”,那么
e.strip=~/\A\D+\z/?1:0,e]
会是什么样的
,可能是
e.strip=~/\D/?0:1
?谢谢,我也考虑过拆分,但它对您没有用scopes@RubyRacer“不适用于作用域”是什么意思?我可以在默认的\u作用域块中使用拆分数组吗?@RubyRacer如果我理解你的问题,你是在问关于在范围内工作的问题。如果是这种情况,那么查询接口也不支持-。您需要一个使用的解决方案。不过,我担心这样的解决方案必须是特定于SQL的,并且可能会根据您使用的数据库进行更改…我正计划尝试转换,如果转换不起作用,我会将订单提交给控制器。谢谢,我也考虑过拆分,但这对我来说没用scopes@RubyRacer“不适用于作用域”是什么意思?我可以在默认的\u作用域块中使用拆分数组吗?@RubyRacer如果我理解你的问题,你是在问关于在范围内工作的问题。如果是这种情况,那么查询接口也不支持-