2013-06-12 18 views
25

Sto eseguendo Ruby 1.9.3p392.ruby ​​sort_by multiple fields

Item = Struct.new(:name, :dir, :sort_dir) 

entries = ftp.list() 
entries.map!{|e| Net::FTP::List.parse(e) }.map!{|e| Item.new(e.basename, e.dir?, (e.dir? ? 0 : 1)) } 

render json: entries.sort_by{ |e| [ e.sort_dir, e.name ]} 

Per qualche motivo, non sto ottenendo i risultati come previsto.

Ricevo innanzitutto tutte le cartelle seguite da tutti i file, tuttavia l'ordinamento dei nomi non funziona.

Per fare un esempio, ottengo questi per le mie cartelle:

  1. contenuti
  2. immagini
  3. bin

Per i file:

  1. global.asax
  2. web.config
  3. favicon.ico

Raggruppa la parte dir/file corretto, ma i nomi sono ordinati in modo non corretto.

L'uscita per la console si presenta così dopo l'ordinamento:

#<struct FtpController::Item name="Content", dir=true, sort_dir=0> 
#<struct FtpController::Item name="Images", dir=true, sort_dir=0> 
#<struct FtpController::Item name="Scripts", dir=true, sort_dir=0> 
#<struct FtpController::Item name="Views", dir=true, sort_dir=0> 
#<struct FtpController::Item name="bin", dir=true, sort_dir=0> 
#<struct FtpController::Item name="Global.asax", dir=false, sort_dir=1> 
#<struct FtpController::Item name="Web.config", dir=false, sort_dir=1> 
#<struct FtpController::Item name="favicon.ico", dir=false, sort_dir=1> 
#<struct FtpController::Item name="packages.config", dir=false, sort_dir=1> 
#<struct FtpController::Item name="robots.txt", dir=false, sort_dir=1> 

risposta

52

vostro ordinamento funziona correttamente in risonanza magnetica di Ruby 1.8.7, 1.9.3, 2.0.0 e:

Item = Struct.new(:name, :dir, :sort_dir) 

entries = [Item.new('favicon.ico', false, 1), Item.new('bin', true, 0), 
      Item.new('web.config', false, 1), Item.new('images', true, 0), 
      Item.new('global.asax', false, 1), Item.new('content', true, 0)] 

entries.sort_by{|e| [e.sort_dir, e.name]} 
# => [#<struct Item name="bin", dir=true, sort_dir=0>, 
#  #<struct Item name="content", dir=true, sort_dir=0>, 
#  #<struct Item name="images", dir=true, sort_dir=0>, 
#  #<struct Item name="favicon.ico", dir=false, sort_dir=1>, 
#  #<struct Item name="global.asax", dir=false, sort_dir=1>, 
#  #<struct Item name="web.config", dir=false, sort_dir=1>] 

Hanno hai provato a pubblicare il risultato del tuo sort_by su una console? Non ho familiarità con la parte del codice render json:, ma forse è lì che le cose stanno andando male. La mia ipotesi migliore è che in qualche modo nella conversione in JSON (se è quello che fa) l'ordinamento si sta incasinando.

L'altra mia idea è che forse ci si aspetta sort_by per modificare entries; non è così. Se si desidera che lo stesso entries venga ordinato dopo la chiamata, utilizzare sort_by! (notare lo ! alla fine del nome del metodo).

Aggiornamento: Sembra che il problema sia la ricerca senza distinzione tra maiuscole e minuscole. Semplicemente aggiungendo upcase dovrebbe fare il trucco:

entries.sort_by{|e| [e.sort_dir, e.name.upcase]} 
+0

Ho incluso l'output della console nella domanda originale. Inoltre, non mi aspetto che le voci stesse vengano ordinate. Mi aspetto che restituisca una lista ordinata al metodo di rendering. Tuttavia, il JSON che torno e l'uscita della console corrisponde. – Mike

+0

@Mike Sembra che il problema sia che si desidera un ordinamento in-sensitive, quindi? Perché il tuo output è ordinato, prima solo maiuscolo. –

+0

puoi aggiungere il tuo commento come risposta in modo da poterlo votare come corretto. Ho aggiunto un downcase per nominare e funziona come previsto. Grazie! – Mike