2017-02-22 5 views
3

Ich arbeite an Ruby auf Schienen und ich bin neu hier auch Ruby on Rails. Ich arbeite an einem Projekt und finde ein Problem beim Sortieren eines Arrays von Zeichenketten, die den Namen des Bildes enthalten. Ich habe viele Algorithmen ausprobiert, von denen ich weiß, dass sie mir nicht helfen. Wenn ich den Dienst zur Bilderfassung anrufe, gibt es mir dieses Array.Wie sortiere ich string array

Beispiel:

["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"] 

Ich möchte wie das dieses Array sortieren:

["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"] 

ich viele Dinge versucht hatte, zu sortieren, aber keine Lösungen erhalten. Bitte hilf mir.

+0

Mögliches Duplikat von [Wie man ein alphanumerisches Array in Ruby sortiert] (http://stackoverflow.com/questions/5480703/how-to-sort-an-alphanumeric-array-in-ruby) –

+0

Wenn Sie ein Beispiel geben (Im Allgemeinen eine gute Sache) Es ist hilfreich, jedem Eingabeobjekt eine Variable zuzuweisen (zB 'arr = [" page-1_1.png ", ...]'). Auf diese Weise können Leser auf diese Variablen in Antworten und Kommentaren verweisen, ohne sie definieren zu müssen. Darüber hinaus beziehen sich alle Leser auf dieselben Variablen, was ebenfalls hilfreich ist. –

Antwort

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

Dies findet alle Zahlen in jedem Dateinamen und Art durch die Zahlen. Beachten Sie, dass Arrays geordnet werden, indem das erste Element verglichen wird, im Falle von Gleichheit - das zweite und so weiter.

+1

Vielen Dank @ndn. – sam

+0

@sam Wenn diese Antwort für Sie funktioniert hat, sollten Sie sie als richtige Antwort markieren, andernfalls wird diese Frage bei Suchen auf der Website als "unbeantwortete" markiert. – eiko

+0

Gute Antwort, ✅. Zur Erklärung kann es hilfreich sein, die Rückgabewerte für 'names.map {| name | name.scan (/ \ d + /)} 'und' names.map {| name | name.scan (/ \ d + /). map (&: to_i)} 'und erklären Sie, dass Sie Arrays vergleichen. –

2

Für das angegebene Array, , hier ist eine Lösung von der Wand.

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"] 

Beachten Sie, dass

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>] 
+0

Es ist wahrscheinlich nicht das gewünschte Verhalten. '% w (1_35 12_0 2_0) .sort_by {| s | s.delete ('_') [/ \ d + /]. to_i} ' –

+0

@Eric, ja, natürlich. Vielen Dank. Ich habe es mit einem meiner Meinung nach besseren Ansatz versehen. –

+0

Sorry, immer noch nicht das gewünschte Verhalten. '1_10' und' 1_1' werden gleich behandelt und '1_11' sollte nach' 1_7' sein –

2

Wenn Sie wissen, dass die Anzahl der Seiten begrenzt ist (zB weniger als 1000), hat dieses Verfahren den Vorteil, alphabetisch und numerisch Sortierung:

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 

Hier sind die temporären Zeichenfolgen, die sortiert werden:

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 
Verwandte Themen