0

我在 S3 存储桶中有几百张图像,我将它们写入一个数组,并希望它们按字母顺序排序和显示。图像都以相同的模式开始

#1 <some name>.jpg
#2 <some name>.jpg
...
#10 <some name>.jpg
#11 <some name>.jpg
...

使用后

@images.each do |image|
@image[i] = image.url_for(:read).to_s
    i = i + 1
end

@image.sort

但是,@image 数组是这样排序的:

<s3 bucket URL>/#1 <some name>.jpg
<s3 bucket URL>/#10 <some name>.jpg
<s3 bucket URL>/#11 <some name>.jpg
...
<s3 bucket URL>/#2 <some name>.jpg
<s3 bucket URL>/#20 <some name>.jpg
<s3 bucket URL>/#21 <some name>.jpg
...

据我了解,“字母表”和排序应该排序 #1、#2、#3 等,但似乎并非如此。显然,我希望它以这种方式排序:

<s3 bucket URL>/#1 <some name>.jpg
<s3 bucket URL>/#2 <some name>.jpg
<s3 bucket URL>/#3 <some name>.jpg
...
<s3 bucket URL>/#10 <some name>.jpg
<s3 bucket URL>/#11 <some name>.jpg
<s3 bucket URL>/#12 <some name>.jpg
...

在这种情况下,我怎么能用排序算法来达到这个目的?谢谢你的帮助。

4

2 回答 2

2

据我了解,“字母表”以及因此排序应该排序 #1、#2、#3 等。

那句话没有任何意义,但在计算机编程字母表中,“1”在“2”之前,当 Ruby 比较字符串时,它会逐个字符地比较字符串,直到找到不同之处。因此,当 Ruby 比较“11”和“2”时,它首先比较第一个字符,这意味着它比较“1”和“2”。因为字符不同,所以不再比较字符;因为“1”在“2”之前,所以字符串“11”在字符串“2”之前。

fnames = [
  "#1 <some name>.jpg",
  "#2 <some name>.jpg",
  "#10 <some name>.jpg",
  "#11 <some name>.jpg",
]


results = fnames.sort_by do |fname|
  match_data = fname.match(/#(\d+)/)
  match_data[1].to_i
end

p results

--output:--
["#1 <some name>.jpg", 
 "#2 <some name>.jpg", 
 "#10 <some name>.jpg", 
 "#11 <some name>.jpg"]

如果你喜欢一个班轮:

results = fnames.sort_by {|fname| fname[/#(\d+)/, 1].to_i }

如果可以有相同数字的文件名,那么您需要做更多的工作:

fnames = [
  "<s3 bucket URL>/#1 <some name>.jpg",
  "<s3 bucket URL>/#10 <some name>.jpg",
  "<s3 bucket URL>/#11 xyz.jpg",
  "<s3 bucket URL>/#11 abc.jpg",
  "<s3 bucket URL>/#2 <some name>.jpg", 
  "<s3 bucket URL>/#20 <some name>.jpg",
  "<s3 bucket URL>/#21 <some name>.jpg",
]

results = fnames.sort_by do |fname| 
  [
    fname[/#(\d+)/, 1].to_i, 
    $'    #The rest of the string after the match
  ]
end


p results

--output:--
["<s3 bucket URL>/#1 <some name>.jpg", 
 "<s3 bucket URL>/#2 <some name>.jpg", 
 "<s3 bucket URL>/#10 <some name>.jpg", 
 "<s3 bucket URL>/#11 abc.jpg", 
 "<s3 bucket URL>/#11 xyz.jpg", 
 "<s3 bucket URL>/#20 <some name>.jpg", 
 "<s3 bucket URL>/#21 <some name>.jpg"]

Ruby 对数组的排序类似于字符串:它比较数组中的第一个元素,如果它们相同,则比较第二个元素,依此类推,直到找到不同之处。该sort_by()块告诉 Ruby 假装每个文件名实际上是一个二元素数组。

于 2013-07-28T21:46:05.427 回答
1
@images.sort_by{ |filename| filename[1..-1].to_i }
于 2013-07-28T21:26:04.933 回答