I have this program in which I store values in a map in this form.
map<string, map<int, CItem, cmpByCnt>> m_Items;
So if I have two items that have the same name, I save them to the "submap". For example, here I have:
map: {
key: beer map: {key: date: 1470783661 count: 50}
key: bread map {key: date: 1461538861 count: 0, key: date: 1461970861 count: 80}
}
How can I delete in this submap?
- For example, if the key (date) 1461538861 with count = 0 delete this record in the submap. But I want to keep key: date: 1461970861 count: 80
so i get
map: {
key: beer map: {key: date: 1470783661 count: 50}
key: bread map {key: date: 1461970861 count: 80}
}
- If I want to delete on the base of the outer key, here: beer, so I will also delete the outer map
so i get
map: {
key: bread map {key: date: 1461970861 count: 80}
}
Maybe I'm at least a little understanding. Thank you for all the comments. Complet program https://onecompiler.com/cpp/3xzqq36xf
class CSupermarket
{
public:
CSupermarket();
CSupermarket& store(const string &name,const CDate &date,const int &cnt);
map<string, map<int, CItem, cmpByCnt>> m_Items;
};
CSupermarket& CSupermarket::store(const string &name,const CDate &date,const int &cnt)
{
CItem a(name, date, cnt);
auto itr = m_Items.find(name);
if ( itr != m_Items.end())
itr->second.emplace(a.m_Date.m_Time, a);
else
m_Items.emplace(name, std::map<int, CItem, cmpByCnt>{{a.m_Date.m_Time, a}});
return *this;
}
int main()
{
CSupermarket s;
s . store ( "bread", CDate ( 2016, 4, 30 ), 100 )
. store ( "butter", CDate ( 2016, 5, 10 ), 10 )
. store ( "beer", CDate ( 2016, 8, 10 ), 50 )
. store ( "bread", CDate ( 2016, 4, 25 ), 100 )
. store ( "okey", CDate ( 2016, 7, 18 ), 5 );
// print
for(auto itr = s.m_Items.begin(); itr != s.m_Items.end(); itr)
{
cout << itr->first << " ";
for(auto i = itr->second.begin(); i != itr->second.end(); i)
{
cout << " date: " << i->first << " count: " << i->second.m_Cnt;
}
cout << endl;
}
}
CodePudding user response:
Deleting an element from a 2d map is almost the same as deleting it from a 1d map. You just want to call .erase
on the inner map.
Say if you have a 1d map:
std::map<int, std::string> m = {
{1, "one" }, {2, "two" }, {3, "three"},
{4, "four"}, {5, "five"}, {6, "six" }
};
To delete {3, "three"}
, you just do:
m.erase(3);
Now if you have a 2d map:
std::map<int, std::map<std::string, std::string>> m = {
{1, {{"en", "one"}, {"es", "uno"}}},
{2, {{"en", "two"}, {"es", "dos"}}},
{3, {{"en", "three"}, {"es", "tres"}}},
{4, {{"en", "four"}, {"es", "cuatro"}}},
};
To access the inner map, you would do:
m[1];
Now, if you want to remove {"en", "one"}
from it, you just do:
m[1].erase("en");
And if you want to remove one of the entire inner map, you would do:
m.erase(3);
Demo: https://godbolt.org/z/aqzGTfc37
One thing to note is that deleting all elements of an inner map will not automatically delete that inner map from the outer map. To remove all the empty inner maps, you can do:
std::erase_if(m, [](auto& item){
auto& [number, inner_map] = item;
return inner_map.size() == 0;
});
Demo: https://godbolt.org/z/hMhMd8Y7b
For C 17 and earlier, there isn't erase_if
function for map
, so instead, you would do something like:
for(auto it = m.begin(); it != m.end();)
{
if(it->second.size() == 0)
{
it = m.erase(it);
}
else it;
}