linux_sa
linux_sa

Reputation: 444

Sort files based on incomplete array of filenames

Given a directory with three files fileA, fileB, fileC, I can make an array of the order I want them sorted like so:

prio = [ "fileC", "fileA", "fileB" ]
#=> ["fileC", "fileA", "fileB"]
Dir.glob("*").sort_by { |i| [prio.index(i), i] }
#=> ["fileC", "fileA", "fileB"]

However, I'm trying to alphabetically sort anything else in the directory after those in the prio array, but as soon as I add a fourth file, I get:

Dir.glob("*").sort_by { |i| [prio.index(i), i] }
ArgumentError: comparison of Array with Array failed
from (irb):3:in `sort_by'
from (irb):3
from :0

I have tried using if prio.include?(i) as a condition inside the block but then I get:

TypeError: can't convert nil into Array from (irb):4:in `<=>'

I am using ruby-1.8.7. Any suggestions?

Upvotes: 1

Views: 56

Answers (2)

the Tin Man
the Tin Man

Reputation: 160571

This looks like it'd do it:

prio = %w[ fileC fileA fileB ]
files = %w[foo fileA bar fileB baz fileC]
prio_files = prio & files  # => ["fileC", "fileA", "fileB"]
non_prio = files - prio_files # => ["foo", "bar", "baz"]
process_order = prio_files + non_prio # => ["fileC", "fileA", "fileB", "foo", "bar", "baz"]

If you want the non_prio files sorted use:

process_order = prio_files + non_prio.sort

See Array's - and & for more information.

Upvotes: 2

Cary Swoveland
Cary Swoveland

Reputation: 110725

[Edit: I initially deleted my answer because it is essentially the same as @theTinMan's, which he had posted a couple of minutes before I posted mine. In light of your comment, however, I've undeleted it just to address your point specifically.]

Does this do what you want?

all_files = Dir.glob("*")
prio & Dir.glob("*") + (all_files-prio).sort

Upvotes: 1

Related Questions