Thinking about it again.. my natural sort doesn't work for "a2002, a20001". Here n1 would be ="2" and n2="01". So n2.toInt() < n1.toInt().. which is wrong, when you look at the whole number..
So from the first different character we also need to look backward and add all adjacent numbers:
bool compareNames(const QString& s1,const QString& s2)
{
// ignore common prefix..
int i = 0;
while ((i < s1.length()) && (i < s2.length()) && (s1.at(i).toLower() == s2.at(i).toLower())) ++i;
++i;
// something left to compare?
if ((i < s1.length()) && (i < s2.length()))
{
// get number prefix from position i - doesnt matter from which string
int k = i-1;QString n = "";
while ((k >= 0) && (s1.at(k).isNumber())) {n = s1.at(k)+n;--k;}
// get relevant/signficant number string for s1
k = i;QString n1 = "";
while ((k < s1.length()) && (s1.at(k).isNumber()) {n1 += s1.at(k);++k;}
// get relevant/signficant number string for s2
k = i;QString n2 = "";
while ((k < s2.length()) && (s2.at(k).isNumber()) {n2 += s2.at(k);++k;}
// got two numbers to compare?
if (!n1.isEmpty() && !n2.isEmpty())
{
return (n+n1).toInt() < (n+n2).toInt();
}
else {
// not a number has to win over a number.. number could have ended earlier... same prefix..
if (!n1.isEmpty()) return false;
if (!n2.isEmpty()) return true;
return s1.at(i) < s2.at(i);
}
}
else {
// shortest string wins
return s1.length() < s2.length();
}
}
bool compareNames(const QString& s1,const QString& s2)
{
// ignore common prefix..
int i = 0;
while ((i < s1.length()) && (i < s2.length()) && (s1.at(i).toLower() == s2.at(i).toLower())) ++i;
++i;
// something left to compare?
if ((i < s1.length()) && (i < s2.length()))
{
// get number prefix from position i - doesnt matter from which string
int k = i-1;QString n = "";
while ((k >= 0) && (s1.at(k).isNumber())) {n = s1.at(k)+n;--k;}
// get relevant/signficant number string for s1
k = i;QString n1 = "";
while ((k < s1.length()) && (s1.at(k).isNumber()) {n1 += s1.at(k);++k;}
// get relevant/signficant number string for s2
k = i;QString n2 = "";
while ((k < s2.length()) && (s2.at(k).isNumber()) {n2 += s2.at(k);++k;}
// got two numbers to compare?
if (!n1.isEmpty() && !n2.isEmpty())
{
return (n+n1).toInt() < (n+n2).toInt();
}
else {
// not a number has to win over a number.. number could have ended earlier... same prefix..
if (!n1.isEmpty()) return false;
if (!n2.isEmpty()) return true;
return s1.at(i) < s2.at(i);
}
}
else {
// shortest string wins
return s1.length() < s2.length();
}
}
To copy to clipboard, switch view to plain text mode
Bookmarks