Hi. Say I have this:
import future
import os
var x = lc[ file | (file <- walkFiles("*")), string]
echo x
Simple program, gets a list of files in a directory and stores them in "x."
If I have {1..11}.jpg in a directory, x would be @[1.jpg, 10.jpg, 11.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg, 6.jpg, 7.jpg, 8.jpg, 9.jpg].
How would I go about sorting this in natural order, as humans expect it to be: @[1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg, 6.jpg, 7.jpg, 8.jpg, 9.jpg, 10.jpg, 11.jpg]?
I looked at http://nedbatchelder.com/blog/200712.html#e20071211T054956, which works for Python, but not for Nim, because the functions can return two different types, int or str.
You could define a function which takes two file names and converts them to -1,0 or 1. I would do something like this:
import future
from algorithm import sort
from os import extract_file_name, walk_files, split_file
from strutils import parse_int, is_digit
proc file_name_cmp(f1, f2: string): int =
let f_name1 = f1.split_file[1]
let f_name2 = f2.split_file[1]
if f_name1.is_digit and f_name2.is_digit:
return system.cmp[int](f_name1.parse_int, f_name2.parse_int)
else:
return system.cmp(f_name1, f_name2)
var x = lc[ file | (file <- walk_files("*")), string]
x.sort(file_name_cmp)
Many thanks. I greatly appreciate it.
I made two small changes, though. I changed line 4 to
from strutils import parse_int, is_digit, toLower
and line 12 to
return system.cmp(f_name1.toLower, f_name2.toLower)
This causes
@[1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg, 6.jpg, 7.jpg, 8.jpg, 9.jpg, 10.jpg, 11.jpg, A1.jpg, C.jpg, F1.png, a0, b.bpg, d.gif]
to instead be sorted as
@[1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg, 6.jpg, 7.jpg, 8.jpg, 9.jpg, 10.jpg, 11.jpg, a0, A1.jpg, b.bpg, C.jpg, d.gif, F1.png]