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
b
can be aQStringList
as 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
5
as the key for thebiz
value taken from thea
map.
I tried to find a function in Qt to do that but it only has toQSet
but 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
b
can be aQStringList
as 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
5
as the key for thebiz
value taken from thea
map.
I tried to find a function in Qt to do that but it only has toQSet
but 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
a
with ``b, it's like searching on
ausing
b` 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
QMap
toQStringList
cause the secondQMap
keys 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
QMap
toQStringList
cause the secondQMap
keys 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
contains
is 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
contains
is 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()); }