[Interest] How to make the QString "10" behind "9" in QMap's key order

Mark Gaiser markg85 at gmail.com
Mon Jan 8 10:50:40 CET 2018


On Mon, Jan 8, 2018 at 4:18 AM, jack ma <assangema at gmail.com> wrote:

> Thanks all of you, seems that std::sort + QCollator is a good way
>
> 2018-01-07 18:47 GMT+08:00 Konstantin Tokarev <annulen at yandex.ru>:
>
>>
>>
>> > Hi,
>> >
>> > you need a "lessThan"-function, tailored for your needs. An
>> > example from me is this:
>> >
>> > bool Person::lessThanFamilyFirst(QSharedPointer<Person>
>> > p1, QSharedPointer<Person>
>> > p2)
>> >
>> > {
>> >
>> > return (QString::localeAwareCompare(p1->familyName(),p2->familyName
>> ())<0)
>> >
>> > || (( p1->familyName() == p2->familyName())
>> >
>> > && (QString::localeAwareCompare(p1->firstName(),p2->firstName())<0));
>> >
>> > }
>> >
>> > Now you can pass this as a functor to a sort method like this:
>> >
>> > std::stable_sort(pupils.begin(), pupils.end(),
>> Person::lessThanFamilyFirst);
>>
>> FWIW, if this is not a list displayed in UI, or other place where
>> preserving order of
>> equal elements matters, you should consider std::sort
>>
>> >
>> > Please notice, that there are no () when calling the lessThan functor.
>>
>> Original question was dealing with QMap. While sorted vector-like
>> container can replace
>> map (there is even convenience wrapper flat_map in Boost, which allows to
>> work with
>> sorted array just like it was a "true" map), it doesn't always fit, e.g.
>> inserts in such
>> "flat map" are very expensive.
>>
>> So, you can just replace QMap with std::map and pass your comparator, e.g.
>>
>> auto comparator = [](const QString &a, const QString &b) -> bool {
>>     // Your comparison function here
>> };
>> std::map<QString, QGraphicsItem *, decltype(comparator)>
>> myMap(comparator);
>>
>> See [1] for more examples.
>>
>> Yet another approach is to use your own type as a key of QMap instead of
>> QString,
>> and create desired operator< for it. This has a downside that your access
>> to internal
>> QString will be more complicated, and you'll have to invent different key
>> type each time
>> you want to change comparator.
>>
>> And, last but not least: you probably want to know *how* to write
>> comparator for your
>> particular sorting order. You can do this with QCollator, see [2].
>>
>> [1] http://en.cppreference.com/w/cpp/container/map/map
>> [2] https://forum.qt.io/topic/68910/natural-sort-using-qcollator/2
>>
>> >
>> > HTH
>> > Sebastian
>> >
>> > Am 07.01.2018 um 09:01 schrieb jack ma:
>> >
>> >> Hi,
>> >>
>> >> there is a QMap<QString,QGraphicsItem *> type, then
>> >> insert values with:
>> >>
>> >> type.insert("U1",nullptr),
>> >>
>> >> type.insert("U2",nullptr),
>> >>
>> >> …………
>> >>
>> >> type.insert("U9",nullptr),
>> >>
>> >> type.insert("U10",nullptr),
>> >>
>> >> I want get the values follow the order of U1, U2 ... U10,
>> >> but the default order is U1, U10 ,……U9
>> >>
>> >> I know this is a common string sorting problem, but I do
>> >> not know how to solve it well.
>> >>
>> >> Any suggestions are very grateful !
>> >>
>> >> Thanks.
>> >>
>> >> _______________________________________________
>> >> Interest mailing list
>> >> Interest at qt-project.org
>> >> http://lists.qt-project.org/mailman/listinfo/interest
>> >
>> > --
>> > http://www.classintouch.de - Tablet-Software für Lehrer
>> --
>> Regards,
>> Konstantin
>> _______________________________________________
>> Interest mailing list
>> Interest at qt-project.org
>> http://lists.qt-project.org/mailman/listinfo/interest
>>
>
>
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
>
>
Hi,

You might want to look into std::map[1] as well. It allows setting a
compare function, QMap doesn't.
Going that route is most likely more efficient as your inserts will be
sorted, no need to do std::sort afterwards.

You still would have to use QCollator. Note that you can just use QCollator
in the compare method which will work just fine, but is not the performant
way to go.
The most performant way (i know of) is by using QCollatorSortKey[2].


[1] http://en.cppreference.com/w/cpp/container/map/map
[2] http://doc.qt.io/qt-5/qcollatorsortkey.html
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20180108/d111edaf/attachment.html>


More information about the Interest mailing list