I have a list of folders that are organised by base36 (0-9 then a-z). Now my current implementation for reading them is to iterate over a number, convert it to base32, check if the folder exists. If it does read the data if it doesn't end.
The problem here is that there are gaps in the folder's numbers. Ex: 0,1,2,4,5,6,8,a,b,开发者_开发技巧c,g,k,p
What would be the best way of iterating over them all, in the correct order (considering there can be any amount of folders)?
(Note: I can't simply get all of the directories, because they'd be ordered alphabetically. 2A for example would be placed before z)
I would probably get all directories into memory, and then sort them rather than try to create something that would guess all possible values in order.
var names = GetAllDirectoryNames();
names.Sort(CompareNames);
foreach( var name in Names)
{
DoSomethingWithDir(name);
}
//...
private static int CompareNames(string x, string y)
{
if( x == null && y == null) return 0;
if( x== null) return -1;
if( y == null) return 1;
var xVal = Base36Decode(x);
var yVal = Base36Decode(y);
if( xVal > yVal) return 1;
if( xVal < yVal) return -1;
return 0;
}
private long Base36Decode(string inputString)
{
var charList = "0123456789abcdefghijklmnopqrstuvwxyz";
inputString = Reverse(inputString.ToLower());
long result = 0;
int position = 0;
foreach (char c in inputString)
{
result += charList.IndexOf(c) * (long)Math.Pow(36, position);
position++;
}
return result;
}
This is effectively a radix sort on your folder names. Sort them all alphabetically first, then sort that by the length of the string.
var names = new[] {"4cc", "2a", "0", "z", "1ab"};
foreach (var n in names.OrderBy(x => x).OrderBy(y => y.Length))
{
Console.WriteLine(n);
}
Yields:
0
z
2a
1ab
4cc
Try this to get them in order:
List<string> b36Items = new List<string>;
//Load with base 36 strings;
List<string> sortedItems = b36Items.OrderBy( t=> Convert.ToInt32(t,36)).ToList();
Documentation for the Convert.ToInt32(string, base) here.
UPDATE
As @Philip Rieck pointed out this will not work with base 36 since the highest base this function works with is 16. I will leave it up for other people who have a similar issue with a smaller base, but you are better off using one of the other solutions. Too bad because this would have been pretty slick...
精彩评论