Skip to content

Instantly share code, notes, and snippets.

@cabo
Created March 3, 2011 18:40
Show Gist options
  • Save cabo/853249 to your computer and use it in GitHub Desktop.
Save cabo/853249 to your computer and use it in GitHub Desktop.
Sort filenames in a natural way
# convert a filename into an array suitable for sorting
def filename_to_sortable(fn)
# convert numeric parts of the string given into actual numbers.
# Keep a string (third element) to disambiguate
fn.scan(/(\D*)(\d*)/).map{ |alpha, numeric| [alpha, numeric.to_i, numeric]}
end
# sort filenames in a "natural" way, keeping numeric parts ascending numerically
def sort_filenames(a)
a.sort_by{ |fn| filename_to_sortable(fn) }
end
if __FILE__ == $0
require 'test/unit'
class FNS_MyTest < Test::Unit::TestCase
def test_single
assert_equal(["1", "2"], sort_filenames(["1", "2"]))
end
def test_numeric_normal
assert_equal(["2", "18"], sort_filenames(["2", "18"]))
end
def test_numeric_inverse
assert_equal(["18", "123"], sort_filenames(["123", "18"]))
end
def test_num_to_alpha
assert_equal(["18", "a123"], sort_filenames(["a123", "18"]))
end
def test_alpha_simple_alpha
assert_equal(["a18a", "a123a"], sort_filenames(["a123a", "a18a"]))
end
def test_alpha_diff_simple_alpha
assert_equal(["a123a", "b18a"], sort_filenames(["a123a", "b18a"]))
end
def test_simple_alpha
assert_equal(["18a", "123a"], sort_filenames(["123a", "18a"]))
end
def test_simple_alpha_diff
assert_equal(["18b", "123a"], sort_filenames(["123a", "18b"]))
end
def test_disambiguate
assert_equal(["a01a", "a1a", "a02a", "a2a"], sort_filenames(["a1a", "a01a", "a2a", "a02a"]))
end
def test_real
sorted = %w(
ti2-ws04-18-0.png
ti2-ws04-18-1.png
ti2-ws04-18-2.png
ti2-ws04-18-3.png
ti2-ws04-18-4.png
ti2-ws04-18-5.png
ti2-ws04-18-6.png
ti2-ws04-18-7.png
ti2-ws04-18-8.png
ti2-ws04-18-9.png
ti2-ws04-18-10.png
ti2-ws04-18-11.png
ti2-ws04-18-12.png
ti2-ws04-18-13.png
ti2-ws04-18-14.png
ti2-ws04-18-15.png
ti2-ws04-18-16.png
ti2-ws04-18-17.png
)
assert_equal(sorted, sort_filenames(sorted.shuffle))
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment