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

Mark Gaiser markg85 at gmail.com
Tue Jan 9 00:06:38 CET 2018


On Mon, Jan 8, 2018 at 8:29 PM, Konstantin Tokarev <annulen at yandex.ru>
wrote:

>
>
> > On Mon, Jan 8, 2018 at 5:25 PM, Konstantin Tokarev <annulen at yandex.ru>
> wrote:
> >
> >> 08.01.2018, 14:34, "Carel Combrink" <carel.combrink at gmail.com>:
> >>
> >>> Hi Mark,
> >>
> >>>
> >>
> >>> How would one use QCollatorSortKey for this type of application?
> >>
> >> Note that you should use QCollatorSortKey if and only if you are going
> to sort same values many times, or use binary search in the sorted vector.
> Otherwise use QCollator.
> >
> > That is not true!
> >
> > I had benchmarked this years ago and using QCollator directly is
> _always_ the slowest path.
> > I had a whole blogpost about that, but that blog went offline... The
> code is still somewhere, but i'm very sure that using QCollator directly is
> never the fastest path in terms of performance, not even for a few entries.
> In terms of ease of use it is the easiest one :)
>
> That's interesting. I thought that QCollatorSortKey is an intermediate
> result of QCollator's comparison algorithm which is serialized in reusable
> form, so in theory sort key should not provide better performance if you do
> one comparison and throw it away
>
> http://userguide.icu-project.org/collation/architecture#TOC-Sort-Keys


Run some benchmarks and you'll see :)
If you want i can search for my old benchmark code. It surely is somewhere,
i just need to find it.

>
>
> >
> >>>
> >>
> >>> Unfortunately I have to say that the Qt documentation on this class is
> not as descriptive compared to other classes.
> >>
> >>>
> >>
> >>> Regards,
> >>
> >>> Carel
> >>
> >>>
> >>
> >>> On Mon, Jan 8, 2018 at 11:50 AM, Mark Gaiser <markg85 at gmail.com>
> wrote:
> >>
> >>>> 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
> >>
> >>>>
> >>
> >>>> _______________________________________________
> >>
> >>>> 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
> >>
> >> --
> >>
> >> Regards,
> >>
> >> Konstantin
> --
> Regards,
> Konstantin
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20180109/78e46078/attachment.html>


More information about the Interest mailing list