Home > Net >  C removing element in map in map
C removing element in map in map

Time:04-21

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?

  1. 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}
         }
  1. 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;
}

Demo: https://godbolt.org/z/aTvPGGT8K

  • Related