Intersection of two QMap
-
I was wondering, how to intersect two
QMap<int, QString>keeping theint, for example:QMap<int, QString> a = { { 0, "foo" }, { 1, "bar" }, { 2, "fez" }, { 3, "fiz" }, { 4, "foz" }, { 5, "biz" } };QMap<int, QString> b = { { 0, "foo" }, { 1, "bar" }, { 2, "biz" } };I just realized something, the
bcan be aQStringListas the key is useless in this cause cause I want only the key from thea.would be:
QMap<int, QString> c = { { 0, "foo" }, { 1, "bar" }, { 5, "biz" } };Notice the
5as the key for thebizvalue taken from theamap.
I tried to find a function in Qt to do that but it only has toQSetbut I need the keys. -
I was wondering, how to intersect two
QMap<int, QString>keeping theint, for example:QMap<int, QString> a = { { 0, "foo" }, { 1, "bar" }, { 2, "fez" }, { 3, "fiz" }, { 4, "foz" }, { 5, "biz" } };QMap<int, QString> b = { { 0, "foo" }, { 1, "bar" }, { 2, "biz" } };I just realized something, the
bcan be aQStringListas the key is useless in this cause cause I want only the key from thea.would be:
QMap<int, QString> c = { { 0, "foo" }, { 1, "bar" }, { 5, "biz" } };Notice the
5as the key for thebizvalue taken from theamap.
I tried to find a function in Qt to do that but it only has toQSetbut I need the keys. -
@Defohin
Maybe you should have a look at QMap::values() -
template <class K, class T> QMap<K,T> intersect(QMap<K,T> collection, const QList<T>& searchList){ for(auto i=collection.begin();i!=collection.end();){ if(searchList.contains(i.value())) ++i; else i=collection.erase(i); } return collection; }Then use:
auto c=intersect(a,b.values()); //move constructor triggered so very cheap -
@the_ How that would help me? I have only the values, I want to intersect
awith ``b, it's like searching onausingb` and keeping the key as well.@Defohin
QMap::values()gets you all values that are stored in the map.
So you could iterate through the one map and compare the actual value with the values of the other map and put it into the result map when it matches.QMap<int, QString> a = { { 0, "foo" }, { 1, "bar" }, { 2, "fez" }, { 3, "fiz" }, { 4, "foz" }, { 5, "biz" } }; QMap<int, QString> b = { { 0, "foo" }, { 1, "bar" }, { 2, "biz" } }; QMap<int, QString> c; QList<QString> localValues = b.values(); for(int x=0;x<a.size();x++) { if(localValues.contains(a.value(x))) c.insert(x,a.value(x)); } qDebug() << c;will print
QMap((0, "foo")(1, "bar")(5, "biz"))
EDIT:
@VRonin's template may be the prefered solution ;) -
@Defohin
QMap::values()gets you all values that are stored in the map.
So you could iterate through the one map and compare the actual value with the values of the other map and put it into the result map when it matches.QMap<int, QString> a = { { 0, "foo" }, { 1, "bar" }, { 2, "fez" }, { 3, "fiz" }, { 4, "foz" }, { 5, "biz" } }; QMap<int, QString> b = { { 0, "foo" }, { 1, "bar" }, { 2, "biz" } }; QMap<int, QString> c; QList<QString> localValues = b.values(); for(int x=0;x<a.size();x++) { if(localValues.contains(a.value(x))) c.insert(x,a.value(x)); } qDebug() << c;will print
QMap((0, "foo")(1, "bar")(5, "biz"))
EDIT:
@VRonin's template may be the prefered solution ;)@the_ It's a really good answer.
I did it that way:
QMap<int, QString> a = { { 0, "foo" }, { 1, "bar" }, { 2, "fez" }, { 3, "fiz" }, { 4, "foz" }, { 5, "biz" } }; QStringList b = { "foo", "bar", "biz" }; QMap<int, QString> inter; foreach (QString value, b) { if (! a.values().contains(value)) continue; inter.insert(a.key(value), value); } qDebug() << inter.keys() << inter.values();I changed the second
QMaptoQStringListcause the secondQMapkeys is kinda useless.If you want to improve the code I sent, feel free to do so
-
@the_ It's a really good answer.
I did it that way:
QMap<int, QString> a = { { 0, "foo" }, { 1, "bar" }, { 2, "fez" }, { 3, "fiz" }, { 4, "foz" }, { 5, "biz" } }; QStringList b = { "foo", "bar", "biz" }; QMap<int, QString> inter; foreach (QString value, b) { if (! a.values().contains(value)) continue; inter.insert(a.key(value), value); } qDebug() << inter.keys() << inter.values();I changed the second
QMaptoQStringListcause the secondQMapkeys is kinda useless.If you want to improve the code I sent, feel free to do so
@Defohin said in Intersection of two QMap:
If you want to improve the code I sent, feel free to do so
use const references in foreach, see http://blog.qt.io/blog/2009/01/23/iterating-efficiently/
If you expect the majority of the values of a not to be in b then use your solution, otherwise, if you expect the majority of a being included in b use my subtractive one
if you do not care about the order of b use QSet as
containsis much faster:QMap<int, QString> a = { { 0, "foo" }, { 1, "bar" }, { 2, "fez" }, { 3, "fiz" }, { 4, "foz" }, { 5, "biz" } }; QSet<QString> b = { "foo", "bar", "biz" }; for(auto i=a.constBegin();i!=a.constEnd();++i){ if(b.contains(i.value())) c.insert(i.key(),i.value()); } -
@Defohin said in Intersection of two QMap:
If you want to improve the code I sent, feel free to do so
use const references in foreach, see http://blog.qt.io/blog/2009/01/23/iterating-efficiently/
If you expect the majority of the values of a not to be in b then use your solution, otherwise, if you expect the majority of a being included in b use my subtractive one
if you do not care about the order of b use QSet as
containsis much faster:QMap<int, QString> a = { { 0, "foo" }, { 1, "bar" }, { 2, "fez" }, { 3, "fiz" }, { 4, "foz" }, { 5, "biz" } }; QSet<QString> b = { "foo", "bar", "biz" }; for(auto i=a.constBegin();i!=a.constEnd();++i){ if(b.contains(i.value())) c.insert(i.key(),i.value()); }