Changeset View
Changeset View
Standalone View
Standalone View
src/propertymaputil_p.h
Show All 17 Lines | |||||
18 | */ | 18 | */ | ||
19 | 19 | | |||
20 | #include <QMap> | 20 | #include <QMap> | ||
21 | #include <KFileMetaData/Properties> | 21 | #include <KFileMetaData/Properties> | ||
22 | #include <KFileMetaData/PropertyInfo> | 22 | #include <KFileMetaData/PropertyInfo> | ||
23 | 23 | | |||
24 | /** | 24 | /** | ||
25 | * Converts the property map into a variant map | 25 | * Converts the property map into a variant map | ||
26 | * using the property name as key. | 26 | * using the property name as key. Converts maps | ||
27 | * with duplicated keys into single entry maps | ||||
28 | * with lists. | ||||
bruns: "In case a key has multiple values, all its values are collected in a QVariantList which is… | |||||
27 | */ | 29 | */ | ||
28 | static inline QVariantMap toNamedVariantMap(const KFileMetaData::PropertyMap& propMap) | 30 | static inline QVariantMap toNamedVariantMap(const KFileMetaData::PropertyMap& propMap) | ||
29 | { | 31 | { | ||
30 | QVariantMap map; | 32 | QVariantMap map; | ||
31 | KFileMetaData::PropertyMap::const_iterator it = propMap.constBegin(); | 33 | | ||
32 | for (; it != propMap.constEnd(); it++) { | 34 | auto uniqueKeys = propMap.uniqueKeys(); | ||
bruns: There is obviously an error here - you wan't to break on `==`. | |||||
33 | KFileMetaData::PropertyInfo pi(it.key()); | 35 | for (const auto& key : uniqueKeys) | ||
34 | map.insertMulti(pi.name(), it.value()); | 36 | { | ||
37 | KFileMetaData::PropertyInfo pi(key); | ||||
bruns: better: `using entry = std::pair<...>`; | |||||
38 | if (propMap.count(key) > 1) { | ||||
bruns: This now has O(n^2) complexity. Please use a nested iterator approach. | |||||
astippich: Something like this? If not, please provide some guidance | |||||
In general, yes. But I think it becomes much nicer when using the algorithms from the standard library: #include <QList> #include <QMap> #include <QString> #include <QDebug> #include <algorithm> int main(int argc, char* argv[]) { QMultiMap<int, QString> map{{0, "zero_0"}, {0, "zero_1"}, {1, "one_0"}, {1, "one_1"}, {1, "one_2"}, {2, "two_0"}, {2, "two_1"}, {2, "two_2"}, {2, "two_3"}, {3, "three"}}; // begin of real code auto begin = map.constKeyValueBegin(); auto rangeEnd = map.constKeyValueBegin(); while (begin != map.constKeyValueEnd()) { std::tie(begin, rangeEnd) = std::equal_range(begin, map.constKeyValueEnd(), *begin, [](const auto& a, const auto& b) { return a.first < b.first; }); auto distance = std::distance(begin, rangeEnd); if (distance > 1) { QList<QString> list; list.reserve(distance); std::for_each(begin, rangeEnd, [&list](const auto& s) { list.append(s.second); }); qDebug() << "multi" << list; } else { qDebug() << "single" << (*begin).second; } begin = rangeEnd; } } bruns: In general, yes.
But I think it becomes much nicer when using the algorithms from the standard… | |||||
39 | map.insert(pi.name(), propMap.values(key)); | ||||
40 | } else { | ||||
41 | map.insert(pi.name(), propMap.value(key)); | ||||
42 | } | ||||
35 | } | 43 | } | ||
36 | 44 | | |||
Just realized this can be even simpler: while (begin != propMap.constKeyValueEnd()) { auto key = (*begin).first; KFileMetaData::PropertyInfo property(key); auto rangeEnd = std::find_if(begin, propMap.constKeyValueEnd(), [key](const entry& e) { return e.first != key; }); ... bruns: Just realized this can be even simpler:
```
while (begin != propMap.constKeyValueEnd()) {… | |||||
37 | return map; | 45 | return map; | ||
38 | } | 46 | } | ||
39 | 47 | |
"In case a key has multiple values, all its values are collected in a QVariantList which is stored as a single entry."