Arrays 如何对字符串数组进行排序

Arrays 如何对字符串数组进行排序,arrays,ruby,sorting,Arrays,Ruby,Sorting,我在RubyonRails上工作,我也是这里的新手。 我在一个项目中工作,发现了对包含图像名称的字符串数组排序的一些问题。我尝试过很多算法,但我知道这些算法对我没有帮助。当我调用图像提取服务时,它会给我这样的数组 示例: ["page-1_1.png", "page-1_10.png", "page-1_11.png", "page-1_2.png", "page-1_3.png", "page-1_4.png", "page-1_5.png", "page-1_6.png",

我在RubyonRails上工作,我也是这里的新手。 我在一个项目中工作,发现了对包含图像名称的字符串数组排序的一些问题。我尝试过很多算法,但我知道这些算法对我没有帮助。当我调用图像提取服务时,它会给我这样的数组

示例:

["page-1_1.png",
 "page-1_10.png",
 "page-1_11.png",
 "page-1_2.png",
 "page-1_3.png",
 "page-1_4.png",
 "page-1_5.png",
 "page-1_6.png",
 "page-1_7.png",
 "page-1_8.png",
 "page-1_9.png"]
["page-1_1.png",
 "page-1_2.png",
 "page-1_3.png",
 "page-1_4.png",
 "page-1_5.png",
 "page-1_6.png",
 "page-1_7.png",
 "page-1_8.png",
 "page-1_9.png",
 "page-1_10.png",
 "page-1_11.png"]
我想对这个数组进行如下排序:

["page-1_1.png",
 "page-1_10.png",
 "page-1_11.png",
 "page-1_2.png",
 "page-1_3.png",
 "page-1_4.png",
 "page-1_5.png",
 "page-1_6.png",
 "page-1_7.png",
 "page-1_8.png",
 "page-1_9.png"]
["page-1_1.png",
 "page-1_2.png",
 "page-1_3.png",
 "page-1_4.png",
 "page-1_5.png",
 "page-1_6.png",
 "page-1_7.png",
 "page-1_8.png",
 "page-1_9.png",
 "page-1_10.png",
 "page-1_11.png"]
我尝试了很多方法来分类,但没有找到任何解决方案。请帮帮我

names.sort_by { |name| name.scan(/\d+/).map(&:to_i) }


这将查找每个文件名中的所有数字,并按所述数字进行排序。请注意,数组是通过比较第一个元素排序的,以此类推。对于给定的数组,
arr
,这里有一个现成的解决方案

require 'ipaddr'

arr.sort_by { |s| IPAddr.new(s.gsub(/\D/) { |c| c == '_' ? '.' : '' } + '.0.0') }
  #=> ["page-1_1.png",
  #    "page-1_2.png",
  #    "page-1_3.png",
  #    "page-1_4.png",
  #    "page-1_5.png",
  #    "page-1_6.png",
  #    "page-1_7.png",
  #    "page-1_10.png",
  #    "page-1_11.png",
  #    "page-3_92.png",
  #    "page-11_8.png"] 
注意

arr.map { |s| IPAddr.new(s.gsub(/\D/) { |c| c == '_' ? '.' : '' } + '.0.0') }
  #=> [#<IPAddr: IPv4:1.1.0.0/255.255.255.255>,
  #    #<IPAddr: IPv4:1.10.0.0/255.255.255.255>,
  #    #<IPAddr: IPv4:1.11.0.0/255.255.255.255>,
  #    #<IPAddr: IPv4:1.2.0.0/255.255.255.255>,
  #    #<IPAddr: IPv4:1.3.0.0/255.255.255.255>,
  #    #<IPAddr: IPv4:1.4.0.0/255.255.255.255>,
  #    #<IPAddr: IPv4:1.5.0.0/255.255.255.255>,
  #    #<IPAddr: IPv4:1.6.0.0/255.255.255.255>,
  #    #<IPAddr: IPv4:1.7.0.0/255.255.255.255>,
  #    #<IPAddr: IPv4:11.8.0.0/255.255.255.255>,
  #    #<IPAddr: IPv4:3.92.0.0/255.255.255.255>] 
arr.map{| s | IPAddr.new(s.gsub(/\D/){| c | c=''u'?':'}+'.0'}
#=> [#,
#    #,
#    #,
#    #,
#    #,
#    #,
#    #,
#    #,
#    #,
#    #,
#    #] 

如果您知道页数是有界的(例如小于1000页),此方法的优点是按字母和数字排序:

arr =
  ['page-1_1.png',
   'page-1_10.png',
   'page-1_11.png',
   'page-1_3.png',
   'page-1_9.png']

puts arr.sort_by{ |str| str.gsub(/\d+/){ |number| number.rjust(3, '0') } }
# page-1_1.png
# page-1_3.png
# page-1_9.png
# page-1_10.png
# page-1_11.png

puts %w(b c a).sort_by{ |str| str.gsub(/\d+/){ |number| number.rjust(3, '0') } }
# a
# b
# c
以下是正在排序的临时字符串:

puts arr.map{ |str| str.gsub(/\d+/){ |number| number.rjust(3, '0') } }
# page-001_001.png
# page-001_010.png
# page-001_011.png
# page-001_003.png
# page-001_009.png

当您给出一个示例(通常是件好事)时,为每个输入对象分配一个变量(例如,
arr=[“page-1_1.png”,…]
)会很有帮助。这样,读者就可以在答案和评论中引用这些变量,而无需定义它们。此外,所有读者都会引用相同的变量,这也很有帮助。@sam如果这个答案对你有效,你应该将它标记为正确答案,否则这个问题将在网站上的搜索中标记为“未回答”。回答得好,✅. 作为解释,显示
names.map{name}name.scan(/\d+/)}
names.map{name}name.scan(/\d+/).map(&:to|i)
的返回值可能会有所帮助,并说明您正在比较数组。请注意,您的方法根本不会对
%w(bca)
进行排序,也不会对
%w(a1a0z1)进行排序
以一种可能令人惊讶的方式。@CarySwoveland,添加了一个高层次的解释。@EricDuminil,没错,但问题似乎与此类情况无关。这可能不是期望的行为<代码>%w(1|35 12|0 2|0)。按{s|s.delete(“|”)[/\d+/]排序。到{u i}@Eric,当然可以。谢谢我用我认为更好的方法解决了这个问题。对不起,这仍然不是我想要的行为
1_10
1_1
被同等对待,
1_11
应该在
1_7
@Eric之后,这很聪明!你应该把它寄出去。我决定选择一些不那么主流的东西。我等待你的反例…@Eric,我放弃了(但我会让我的答案代表可能的娱乐价值)!英雄联盟