Deleting multiple elements from the map as I am iterating over it

114 views Asked by At

I have a map<string, string> which has UserNames as Keys, and I need to get Ids for those userNames. I am doing this in batches of 20 as calling api for every user may be a bit of an issue. So once I get the response to all those 20 items(failed or successful), I would like to delete the successful usernames from the map. I know the method of erasing while iterating over the map, but that is for a single element at a time. How can I achieve this?

for (auto it = myMap.begin(); it != myMap.end();it++)//myMap is a class variable {          
  keys.push_back(it->first);
  values.push_back(it->second);

  if (keys.size() != BATCH_SIZE)
    continue;
                
  vector<string> response = BatchGetResponse(keys);
  it = ParseResponse(keys, values, response);
}

std::map<string, string>::iterator ParseResponse(vector<string>& keys,vector<string>& values, vector<string>& reponse)
{
    auto it = myMap.begin();
    for (int i = 0; i < int(values.size()); i++) {
        if (response[i] == "")
            continue;
        it = myMap.erase(myMap.find(keys[i]));
        updateMap(objectGuidsOfPaths[i], response[i]);
    }
    keys.clear();
    values.clear();
    return it;
}

Is this the right way to do this, I am not sure what would be the behaviour if I don't get successful response for any of the 20 elements as the iterator would point to myMap.begin()

1

There are 1 answers

0
r123 On

I am not sure what you are doing and asking exacly.

Calling map::erase like this returns the iterator that comes AFTER the deleted element.

Thus if you delete the last element you might return myMap.end() Then your first for-loop will first increment the iterator before testing to see if it is myMap.end(). This is undefined behavior.