
Originally Posted by
Gizmo
Nice function, very useful. Therefore I think there is a mistake on the indexes and for my part I would add a test if there is no number.
There's a slight error in the code I posted. If for example the number to compare is not at the end of the string, before ".jpg" but at the beginning followed by a underscore ("_"). The function will return a wrong and unstable value. Why? Because "." is before numbers and "_" after numbers in the ASCII table. As long as I am doing the native comparison for two numbers with a different length, a bug should pop up. Example with "1_..." & "12_..." sometimes it will return true sometimes false. But it should return the smallest which is always "1" (1 < 12).
bool SailSlideShowWidget::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;
//If not number return native comparator
if(!s1.at(k).isNumber() || !s2.at(k).isNumber())
{
//Two next lines
//E.g. 1_... < 12_...
if(s1.at(k).isNumber())
return false;
if(s2.at(k).isNumber())
return true;
return QString::compare(s1, s2, Qt
::CaseSensitive) <
0;
}
k--;
while ((k >= 0) && (s1.at(k).isNumber()))
{
n = s1.at(k)+n;
--k;
}
// get relevant/signficant number string for s1
k = i-1;
while ((k < s1.length()) && (s1.at(k).isNumber()))
{
n1 += s1.at(k);
++k;
}
// get relevant/signficant number string for s2
//Decrease by
k = i-1;
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 SailSlideShowWidget::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;
//If not number return native comparator
if(!s1.at(k).isNumber() || !s2.at(k).isNumber())
{
//Two next lines
//E.g. 1_... < 12_...
if(s1.at(k).isNumber())
return false;
if(s2.at(k).isNumber())
return true;
return QString::compare(s1, s2, Qt::CaseSensitive) < 0;
}
QString n = "";
k--;
while ((k >= 0) && (s1.at(k).isNumber()))
{
n = s1.at(k)+n;
--k;
}
// get relevant/signficant number string for s1
k = i-1;
QString n1 = "";
while ((k < s1.length()) && (s1.at(k).isNumber()))
{
n1 += s1.at(k);
++k;
}
// get relevant/signficant number string for s2
//Decrease by
k = i-1;
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
I hope this is correct and at least now I get a decent result with all strings.
Giz
Bookmarks