Changeset View
Changeset View
Standalone View
Standalone View
src/propertymaputil_p.h
Show All 15 Lines | |||||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | * | 17 | * | ||
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 | #include <algorithm> | ||||
25 | | ||||
24 | /** | 26 | /** | ||
25 | * Converts the property map into a variant map | 27 | * Converts the property map into a variant map | ||
26 | * using the property name as key. | 28 | * using the property name as key. Converts maps | ||
29 | * with duplicated keys into single entry maps | ||||
30 | * with lists. | ||||
bruns: "In case a key has multiple values, all its values are collected in a QVariantList which is… | |||||
27 | */ | 31 | */ | ||
28 | static inline QVariantMap toNamedVariantMap(const KFileMetaData::PropertyMap& propMap) | 32 | static inline QVariantMap toNamedVariantMap(const KFileMetaData::PropertyMap& propMap) | ||
29 | { | 33 | { | ||
30 | QVariantMap map; | 34 | QVariantMap map; | ||
31 | KFileMetaData::PropertyMap::const_iterator it = propMap.constBegin(); | 35 | if (propMap.isEmpty()) { | ||
32 | for (; it != propMap.constEnd(); it++) { | 36 | return map; | ||
37 | } | ||||
38 | | ||||
39 | auto it = propMap.constBegin(); | ||||
40 | while (it != propMap.constEnd()) { | ||||
33 | KFileMetaData::PropertyInfo pi(it.key()); | 41 | KFileMetaData::PropertyInfo pi(it.key()); | ||
34 | map.insertMulti(pi.name(), it.value()); | 42 | auto range = propMap.equal_range(it.key()); | ||
43 | auto distance = std::distance(range.first, range.second); | ||||
bruns: There is obviously an error here - you wan't to break on `==`. | |||||
44 | if (distance > 1) { | ||||
45 | QVariantList list; | ||||
46 | list.reserve(static_cast<int>(distance)); | ||||
bruns: better: `using entry = std::pair<...>`; | |||||
47 | for (int i = 0; i < distance; ++i) { | ||||
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… | |||||
48 | list.append(it.value()); | ||||
49 | ++it; | ||||
50 | } | ||||
51 | map.insert(pi.name(), list); | ||||
52 | } else { | ||||
53 | map.insert(pi.name(), it.value()); | ||||
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()) {… | |||||
54 | ++it; | ||||
55 | } | ||||
35 | } | 56 | } | ||
36 | 57 | | |||
37 | return map; | 58 | return map; | ||
38 | } | 59 | } | ||
39 | 60 | |
"In case a key has multiple values, all its values are collected in a QVariantList which is stored as a single entry."