Results 1 to 20 of 20

Thread: QStringList Sorting

  1. #1
    Join Date
    Jul 2008
    Posts
    139
    Thanks
    9
    Thanked 18 Times in 15 Posts
    Qt products
    Qt/Embedded
    Platforms
    Unix/X11

    Default QStringList Sorting

    Hi,
    I have a QStringList in which I am trying to sort before I insert into a QComboBox.
    The names are "background1.jpg, background2.jpg... background15.jpg. or user1..userX.jpg
    The sort applies the order as such:
    background1.jpg
    background10.jpg
    background11.jpg..
    background2.jpg..etc

    I need the list sorted in this order.
    background1.jpg
    background2.jpg
    background3.jpg
    ...background10.jpg
    background11.jpg

    I have read the QMap but I cannot understand how to apply the sorting method I am looking for. Can anyone suggest a method?

    Here is my code, it will either get my background files from a USB drive (for copying) or from the local filesystem for selecting in a combobox.
    Qt Code:
    1. QStringList getBackGroundFiles(int val)
    2. {
    3. QDir dir;
    4. if (val == LOCAL)
    5. dir.setPath(BKGNDIMAGEPATHLOCAL);
    6. else
    7. dir.setPath(BACKIMAGEPATH);
    8. QStringList fileFilter,fileNames,names;
    9. fileFilter << "*.jpg" << "*.bmp";
    10. dir.setNameFilters(fileFilter);
    11. names << "user*" << "background*";
    12. fileNames = dir.entryList(names,QDir::Files);
    13. fileNames.sort();
    14. return fileNames;
    15. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jun 2007
    Location
    India
    Posts
    1,042
    Thanks
    8
    Thanked 133 Times in 128 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Question Re: QStringList Sorting

    use qSort()

    Qt Code:
    1. qSort(filenames.begin(),filenames.end(),compareNames)
    2.  
    3. bool compareNames(const QString& s1,const QString& s2)
    4. {
    5. //apply section(),mid() or whatever to take out the integer part and compare
    6.  
    7. //for example if all the strings are like "userXXX.jpg"
    8. QString temp1=s1.section("user",1);//temp1=="XXX.jpg";
    9. temp1=temp1.section('.',0,0);//temp1=="XXX"
    10.  
    11. QString temp2=s2.section("user",1);
    12. temp2=temp2.section('.',0,0);
    13.  
    14. return (temp1.toInt()<temp2.toInt());
    15.  
    16. //your code would be more complicated than this as u have different file names
    17. //and filenames may also contain periods(.) more than once
    18.  
    19.  
    20. }
    To copy to clipboard, switch view to plain text mode 

    hope this helps
    Last edited by nish; 1st June 2009 at 03:49.

  3. The following user says thank you to nish for this useful post:

    QbelcorT (1st June 2009)

  4. #3
    Join Date
    Jul 2008
    Posts
    139
    Thanks
    9
    Thanked 18 Times in 15 Posts
    Qt products
    Qt/Embedded
    Platforms
    Unix/X11

    Default Re: QStringList Sorting

    Thank you. It pointed me in the right direction. This modified sorting technique works as I want it to. There are 15 background and 9 user. So I do not need to worry about sorting the "user" numbers. I just need to make sure it is sorted alpabetically, by numbers.
    background1.jpg
    background2.jpg..
    background15.jpg
    user1.jpg..
    user9.jpg

    Qt Code:
    1. bool compareNames(const QString& s1,const QString& s2)
    2. {
    3. //for example if all the strings are like "userXXX.jpg"
    4. QString temp1=s1.section("background",1);//temp1=="XXX.jpg";
    5. temp1=temp1.section('.',0,0); //temp1=="XXX"
    6. QString temp2=s2.section("background",1);
    7. temp2=temp2.section('.',0,0);
    8. if (s1.contains("user",Qt::CaseInsensitive) || s2.contains("user",Qt::CaseInsensitive))
    9. return(s1.toLower() < s2.toLower()); // return the string sorted alpabetically
    10. else
    11. return (temp1.toInt()<temp2.toInt()); // return the file no sorted numerically
    12. }
    To copy to clipboard, switch view to plain text mode 

  5. #4
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Cool Re: QStringList Sorting

    Hi there!

    Just read this.. and thought that hardcoding "background" probably isn't the most beautiful approach :->

    What about this:

    Qt Code:
    1. bool compareNames(const QString& s1,const QString& s2)
    2. {
    3. // ignore common prefix..
    4. int i = 0;
    5. while ((i < s1.length()) && (i < s2.length()) && (s1.at(i).toLower() == s2.at(i).toLower())) ++i;
    6. ++i;
    7. // something left to compare?
    8. if ((i < s1.length()) && (i < s2.length()))
    9. {
    10. // get relevant/signficant number string for s1
    11. int k = i;QString n1 = "";
    12. while ((k < s1.length()) && (s1.at(k).isNumber()) {n1 += s1.at(k);++k;}
    13.  
    14. // get relevant/signficant number string for s2
    15. k = i;QString n2 = "";
    16. while ((k < s2.length()) && (s2.at(k).isNumber()) {n2 += s2.at(k);++k;}
    17.  
    18. // got two numbers to compare?
    19. if (!n1.isEmpty() && !n2.isEmpty())
    20. {
    21. return n1.toInt() < n2.toInt();
    22. }
    23. else {
    24. // not a number has to win over a number.. number could have ended earlier... same prefix..
    25. if (!n1.isEmpty()) return false;
    26. if (!n2.isEmpty()) return true;
    27. return s1.at(i) < s2.at(i);
    28. }
    29. }
    30. else {
    31. // shortest string wins
    32. return s1.length() < s2.length();
    33. }
    34. }
    To copy to clipboard, switch view to plain text mode 

    Didn't compile/test this.. just to give you the idea.. Should also be able to sort something like: "abc 10.1.txt, abc 1.4.txt, abc 10.10.txt, def 1.txt"

    Now I can forget about this again :->

    Joh

    Edit: Added to Lower in the prefix compare..
    Edit: Added empty case.. more complicated than I thought.. should test this.. :->
    Last edited by JohannesMunk; 1st June 2009 at 13:55.

  6. #5
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: QStringList Sorting

    Hi,

    a lot of loops, QRegExp would might be the better solution to separate any prefix from counting at the end...

    Quote Originally Posted by JohannesMunk View Post
    Should also be able to sort something like: "abc 10.1.txt, abc 1.4.txt, abc 10.10.txt, def 1.txt"
    No, because of:

    Qt Code:
    1. while ((k < s1.length()) && (s1.at(k).isNumber()) {n1 += s1.at(k);++k;}
    To copy to clipboard, switch view to plain text mode 
    Example:

    bla_10.1.txt => 101
    bla_2.34.txt => 234

    ==> order will be 10.1, 2.34

    Beside points in file names aren't the best decision.



    That's just a quick note.

  7. #6
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QStringList Sorting

    Quote Originally Posted by Lykurg View Post
    Hi,
    a lot of loops, QRegExp would might be the better solution to separate any prefix from counting at the end...
    Yeah.. thought about QRegExp.. but than.. it occured to me.. that maybe the file list might get bigger than two entries.. and than creating a QRegExp for each n*log(n) compares is really slow. And BTW.. QRegExp needs to loop over the characters as well!

    Quote Originally Posted by Lykurg View Post
    No, because of:
    Example:

    bla_10.1.txt => 101
    bla_2.34.txt => 234
    No.. the while goes on only as long as it finds numbers.. read it again!

    Quote Originally Posted by Lykurg View Post
    That's just a quick note.
    Too quick, I'm afraid!

  8. #7
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: QStringList Sorting

    Ok, I see, too quick

    But with "abc-2.00234" and "abc-2.12352" n1 == n2 == 2?

    Anyway, may it not be better/quicker first to determinate the number on the end of the string, and then chop the x characters (x = length of the determinated number)? Of course it depends of the string list you compare. Many different prefixes exterminating from the front would be faster...


    Also interesting would be a speed comparison with a member reg expression...

  9. #8
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QStringList Sorting

    Quote Originally Posted by Lykurg View Post
    Ok, I see, too quick
    But with "abc-2.00234" and "abc-2.12352" n1 == n2 == 2?
    No! "abc-2." would fall into the common prefix (while s1.at(i) == s2.at(i)). Thus: n1="00234", n2="12352"

    Quote Originally Posted by Lykurg View Post
    Anyway, may it not be better/quicker first to determinate the number on the end of the string, and then chop the x characters (x = length of the determinated number)? Of course it depends of the string list you compare. Many different prefixes exterminating from the front would be faster...
    Well the last number could be equal. I think the approach to find the biggest common prefix and then look for the difference is the way to go. Thats how a natural/human sort does work anyway.

    Quote Originally Posted by Lykurg View Post
    Also interesting would be a speed comparison with a member reg expression...
    There is no doubt in my mind, that the explicit while loop will be faster. Even when you use a member RegExp, so that its mask-parsing is only done once.. the reg-exp-fitting code is much more general and thus carries a lot of overhead, compared to this specialized solution..

    The code would perhaps be more readable.. But I'm not so sure :->

    Greetings!

    Joh

  10. #9
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QStringList Sorting

    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:

    Qt Code:
    1. bool compareNames(const QString& s1,const QString& s2)
    2. {
    3. // ignore common prefix..
    4. int i = 0;
    5. while ((i < s1.length()) && (i < s2.length()) && (s1.at(i).toLower() == s2.at(i).toLower())) ++i;
    6. ++i;
    7. // something left to compare?
    8. if ((i < s1.length()) && (i < s2.length()))
    9. {
    10. // get number prefix from position i - doesnt matter from which string
    11. int k = i-1;QString n = "";
    12. while ((k >= 0) && (s1.at(k).isNumber())) {n = s1.at(k)+n;--k;}
    13.  
    14. // get relevant/signficant number string for s1
    15. k = i;QString n1 = "";
    16. while ((k < s1.length()) && (s1.at(k).isNumber()) {n1 += s1.at(k);++k;}
    17.  
    18. // get relevant/signficant number string for s2
    19. k = i;QString n2 = "";
    20. while ((k < s2.length()) && (s2.at(k).isNumber()) {n2 += s2.at(k);++k;}
    21.  
    22. // got two numbers to compare?
    23. if (!n1.isEmpty() && !n2.isEmpty())
    24. {
    25. return (n+n1).toInt() < (n+n2).toInt();
    26. }
    27. else {
    28. // not a number has to win over a number.. number could have ended earlier... same prefix..
    29. if (!n1.isEmpty()) return false;
    30. if (!n2.isEmpty()) return true;
    31. return s1.at(i) < s2.at(i);
    32. }
    33. }
    34. else {
    35. // shortest string wins
    36. return s1.length() < s2.length();
    37. }
    38. }
    To copy to clipboard, switch view to plain text mode 

  11. #10
    Join Date
    Apr 2009
    Posts
    25
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QStringList Sorting

    I want to do the same thing sort of a class QStrings as integers. But I don't know where to put the functinon compareNames. As a class function? Or should I extend the qSort class?

  12. #11
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QStringList Sorting

    qSort is not a class but function.
    make your function compareNames as a global function or static class method or a struct with operator() (and pass object of that struct).
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  13. #12
    Join Date
    Sep 2009
    Posts
    36
    Thanks
    4
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QStringList Sorting

    I'd suggest first to determine the name sheme before throwing solutions at each other and then just use the one that fits the purpose....

  14. #13
    Join Date
    Oct 2008
    Posts
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QStringList Sorting

    For an implementation of Natural-Order Sorting (Case sensitive or non) you can have a look at the GPL code by Tobias Koenig <tokoe@kde.org> in these links: [Header - qnatsort.h] [Source - qnatsort.cpp]

    An implementation using qSort() is explained in the comments - you simply have to pass the included function.

  15. #14
    Join Date
    May 2009
    Posts
    94
    Thanks
    10
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QStringList Sorting

    in qsort you are passing comparenames, comparenames taking two string parameter, what are those parameter we need to give?

  16. #15
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QStringList Sorting

    In the above examples we provided our own LessThan-function, so we were using this qsort definition:

    Qt Code:
    1. template <typename RandomAccessIterator, typename LessThan>
    2. inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
    To copy to clipboard, switch view to plain text mode 

    The third argument is a function pointer to a user-defined-function with two parameters of the container type, that returns true only if the first argument is "less" than the second.

    Qt Code:
    1. bool compareNames(const T &t1, const T &t2) const ..
    To copy to clipboard, switch view to plain text mode 

    So you do not give any parameters to compareNames. You just call:

    Qt Code:
    1. qSort(strlist.begin(),strlist.end(),compareNames);
    To copy to clipboard, switch view to plain text mode 

    qSort then calls compareNames each time it needs to establish the order of two strings while sorting the whole thing.

    HIH

    Johannes

  17. #16
    Join Date
    May 2009
    Posts
    94
    Thanks
    10
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QStringList Sorting

    passing comparenames as 3rd paramete in qsort, it is giving a error that

    rror C2664: 'void __cdecl qSort(class QList<class QString>::iterator,class QList<class QString>::iterator,bool (__thiscall *)(const class QString &,const class QString &))' : cannot convert parameter 3 from 'bool
    (const class QString &,const class QString &)' to 'bool (__thiscall *)(const class QString &,const class QString &)'
    None of the functions with this name in scope match the target type.

    How i will pass comparenames as a parameter?

  18. #17
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QStringList Sorting

    compareNames must be a plain method, not a member function.

    Below you can see a complete code example, that compiles and works as it should.

    Qt Code:
    1. #include <QtGui>
    2. #include <QStringList>
    3. #include <QDebug>
    4.  
    5. bool compareNames(const QString& s1,const QString& s2)
    6. {
    7. // ignore common prefix..
    8. int i = 0;
    9. while ((i < s1.length()) && (i < s2.length()) && (s1.at(i).toLower() == s2.at(i).toLower())) ++i;
    10. ++i;
    11. // something left to compare?
    12. if ((i < s1.length()) && (i < s2.length()))
    13. {
    14. // get number prefix from position i - doesnt matter from which string
    15. int k = i-1;QString n = "";
    16. while ((k >= 0) && (s1.at(k).isNumber())) {n = s1.at(k)+n;--k;}
    17.  
    18. // get relevant/signficant number string for s1
    19. k = i;QString n1 = "";
    20. while ((k < s1.length()) && (s1.at(k).isNumber())) {n1 += s1.at(k);++k;}
    21.  
    22. // get relevant/signficant number string for s2
    23. k = i;QString n2 = "";
    24. while ((k < s2.length()) && (s2.at(k).isNumber())) {n2 += s2.at(k);++k;}
    25.  
    26. // got two numbers to compare?
    27. if (!n1.isEmpty() && !n2.isEmpty())
    28. {
    29. return (n+n1).toInt() < (n+n2).toInt();
    30. }
    31. else {
    32. // not a number has to win over a number.. number could have ended earlier... same prefix..
    33. if (!n1.isEmpty()) return false;
    34. if (!n2.isEmpty()) return true;
    35. return s1.at(i) < s2.at(i);
    36. }
    37. }
    38. else {
    39. // shortest string wins
    40. return s1.length() < s2.length();
    41. }
    42. }
    43.  
    44. int main(int argc, char *argv[])
    45. {
    46. QApplication a(argc, argv);
    47.  
    48. QStringList strlist;
    49. strlist << "a_9898" << "a_55" << "a_100000";
    50.  
    51. qSort(strlist.begin(),strlist.end(),compareNames);
    52.  
    53. qDebug() << strlist;
    54.  
    55. return 0;
    56. }
    To copy to clipboard, switch view to plain text mode 

    Johannes

  19. #18
    Join Date
    Nov 2010
    Posts
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: QStringList Sorting

    Quote Originally Posted by JohannesMunk View Post
    compareNames must be a plain method, not a member function.

    Below you can see a complete code example, that compiles and works as it should.
    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.
    Qt Code:
    1. bool SailSlideShowWidget::compareNames(const QString& s1,const QString& s2)
    2. {
    3. // ignore common prefix..
    4. int i = 0;
    5. while ((i < s1.length()) && (i < s2.length()) && (s1.at(i).toLower() == s2.at(i).toLower()))
    6. ++i;
    7. ++i;
    8. // something left to compare?
    9. if ((i < s1.length()) && (i < s2.length()))
    10. {
    11. // get number prefix from position i - doesnt matter from which string
    12. int k = i-1;
    13. //If not number return native comparator
    14. if(!s1.at(k).isNumber() || !s2.at(k).isNumber())
    15. {
    16. return QString::compare(s1, s2, Qt::CaseSensitive) < 0;
    17. }
    18. QString n = "";
    19. k--;
    20. while ((k >= 0) && (s1.at(k).isNumber()))
    21. {
    22. n = s1.at(k)+n;
    23. --k;
    24. }
    25. // get relevant/signficant number string for s1
    26. k = i-1;
    27. QString n1 = "";
    28. while ((k < s1.length()) && (s1.at(k).isNumber()))
    29. {
    30. n1 += s1.at(k);
    31. ++k;
    32. }
    33.  
    34. // get relevant/signficant number string for s2
    35. //Decrease by
    36. k = i-1;
    37. QString n2 = "";
    38. while ((k < s2.length()) && (s2.at(k).isNumber()))
    39. {
    40. n2 += s2.at(k);
    41. ++k;
    42. }
    43.  
    44. // got two numbers to compare?
    45. if (!n1.isEmpty() && !n2.isEmpty())
    46. {
    47. return (n+n1).toInt() < (n+n2).toInt();
    48. }
    49. else
    50. {
    51. // not a number has to win over a number.. number could have ended earlier... same prefix..
    52. if (!n1.isEmpty())
    53. return false;
    54. if (!n2.isEmpty())
    55. return true;
    56. return s1.at(i) < s2.at(i);
    57. }
    58. }
    59. else {
    60. // shortest string wins
    61. return s1.length() < s2.length();
    62. }
    63. }
    To copy to clipboard, switch view to plain text mode 

    Thank you anyway for that!
    Giz

  20. #19
    Join Date
    Nov 2010
    Posts
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: QStringList Sorting

    Quote Originally Posted by Gizmo View Post
    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).
    Qt Code:
    1. bool SailSlideShowWidget::compareNames(const QString& s1,const QString& s2)
    2. {
    3. // ignore common prefix..
    4. int i = 0;
    5. while ((i < s1.length()) && (i < s2.length()) && (s1.at(i).toLower() == s2.at(i).toLower()))
    6. ++i;
    7. ++i;
    8. // something left to compare?
    9. if ((i < s1.length()) && (i < s2.length()))
    10. {
    11. // get number prefix from position i - doesnt matter from which string
    12. int k = i-1;
    13. //If not number return native comparator
    14. if(!s1.at(k).isNumber() || !s2.at(k).isNumber())
    15. {
    16. //Two next lines
    17. //E.g. 1_... < 12_...
    18. if(s1.at(k).isNumber())
    19. return false;
    20. if(s2.at(k).isNumber())
    21. return true;
    22. return QString::compare(s1, s2, Qt::CaseSensitive) < 0;
    23. }
    24. QString n = "";
    25. k--;
    26. while ((k >= 0) && (s1.at(k).isNumber()))
    27. {
    28. n = s1.at(k)+n;
    29. --k;
    30. }
    31. // get relevant/signficant number string for s1
    32. k = i-1;
    33. QString n1 = "";
    34. while ((k < s1.length()) && (s1.at(k).isNumber()))
    35. {
    36. n1 += s1.at(k);
    37. ++k;
    38. }
    39.  
    40. // get relevant/signficant number string for s2
    41. //Decrease by
    42. k = i-1;
    43. QString n2 = "";
    44. while ((k < s2.length()) && (s2.at(k).isNumber()))
    45. {
    46. n2 += s2.at(k);
    47. ++k;
    48. }
    49.  
    50. // got two numbers to compare?
    51. if (!n1.isEmpty() && !n2.isEmpty())
    52. return (n+n1).toInt() < (n+n2).toInt();
    53. else
    54. {
    55. // not a number has to win over a number.. number could have ended earlier... same prefix..
    56. if (!n1.isEmpty())
    57. return false;
    58. if (!n2.isEmpty())
    59. return true;
    60. return s1.at(i) < s2.at(i);
    61. }
    62. }
    63. else
    64. {
    65. // shortest string wins
    66. return s1.length() < s2.length();
    67. }
    68. }
    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

  21. #20
    Join Date
    Jun 2007
    Location
    India
    Posts
    1,042
    Thanks
    8
    Thanked 133 Times in 128 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QStringList Sorting

    Quote Originally Posted by Gizmo View Post
    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).
    Qt Code:
    1. bool SailSlideShowWidget::compareNames(const QString& s1,const QString& s2)
    2. {
    3. // ignore common prefix..
    4. int i = 0;
    5. while ((i < s1.length()) && (i < s2.length()) && (s1.at(i).toLower() == s2.at(i).toLower()))
    6. ++i;
    7. ++i;
    8. // something left to compare?
    9. if ((i < s1.length()) && (i < s2.length()))
    10. {
    11. // get number prefix from position i - doesnt matter from which string
    12. int k = i-1;
    13. //If not number return native comparator
    14. if(!s1.at(k).isNumber() || !s2.at(k).isNumber())
    15. {
    16. //Two next lines
    17. //E.g. 1_... < 12_...
    18. if(s1.at(k).isNumber())
    19. return false;
    20. if(s2.at(k).isNumber())
    21. return true;
    22. return QString::compare(s1, s2, Qt::CaseSensitive) < 0;
    23. }
    24. QString n = "";
    25. k--;
    26. while ((k >= 0) && (s1.at(k).isNumber()))
    27. {
    28. n = s1.at(k)+n;
    29. --k;
    30. }
    31. // get relevant/signficant number string for s1
    32. k = i-1;
    33. QString n1 = "";
    34. while ((k < s1.length()) && (s1.at(k).isNumber()))
    35. {
    36. n1 += s1.at(k);
    37. ++k;
    38. }
    39.  
    40. // get relevant/signficant number string for s2
    41. //Decrease by
    42. k = i-1;
    43. QString n2 = "";
    44. while ((k < s2.length()) && (s2.at(k).isNumber()))
    45. {
    46. n2 += s2.at(k);
    47. ++k;
    48. }
    49.  
    50. // got two numbers to compare?
    51. if (!n1.isEmpty() && !n2.isEmpty())
    52. return (n+n1).toInt() < (n+n2).toInt();
    53. else
    54. {
    55. // not a number has to win over a number.. number could have ended earlier... same prefix..
    56. if (!n1.isEmpty())
    57. return false;
    58. if (!n2.isEmpty())
    59. return true;
    60. return s1.at(i) < s2.at(i);
    61. }
    62. }
    63. else
    64. {
    65. // shortest string wins
    66. return s1.length() < s2.length();
    67. }
    68. }
    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
    Man, you do remember to fix your code! After almost an year!!

Similar Threads

  1. QStringList
    By jaca in forum Qt Programming
    Replies: 5
    Last Post: 17th May 2008, 10:12
  2. QStringList in QObject::connect
    By DPinLV in forum Qt Programming
    Replies: 6
    Last Post: 6th September 2006, 17:01
  3. Cannot queue arguments of type 'QStringList'
    By vfernandez in forum Qt Programming
    Replies: 2
    Last Post: 19th April 2006, 20:48
  4. [QT4] QTreeView, QAbstractItemModel and sorting
    By KShots in forum Qt Programming
    Replies: 3
    Last Post: 24th March 2006, 20:16
  5. need help to classify some QStringList
    By patcito in forum Qt Programming
    Replies: 3
    Last Post: 17th February 2006, 21:24

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.