I'm running Ruby 1.9.3p392.
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 ]}
For some reason, I am not getting the results back as expected.
I do get all folders first followed by all files, however, the name sorting is failing.
As an example, I get these for my folders:
For files:
It groups the dir/file portion correct, but the names are sorted incorrectly.
The output to the console looks like this after sorting:
#<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>
Your sorting works correctly in MRI Ruby 1.8.7, 1.9.3, and 2.0.0:
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>]
Have you tried outputting the result of your sort_by
to a console? I'm not familiar with the render json:
portion of your code, but perhaps that's where things are going wrong. My best guess is that somehow in the conversion to JSON (if that's what it does) the sorting is getting messed up.
My other idea is that perhaps you expect sort_by
to modify entries
; it does not. If you want entries
itself to be sorted after the call, use sort_by!
(note the !
at the end of the method name).
Update: It looks like the issue is that you want a case-insensitive search. Simply adding upcase
should do the trick:
entries.sort_by{|e| [e.sort_dir, e.name.upcase]}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With