bbtrb
bbtrb

Reputation: 4085

Is there a more elegant way to conditionally insert into a std::map of std::maps?

I have nested containers std::map<int, std::map<T, U> > and want to populate them properly, either inserting a new sub map or appending to the sub map if the integer key exists. So I came up with something like the following example:

int n = ...;
int m = ...;
obj get_some_random_obj(int i, int j);        // returns some object 

std::map<int, std::map<int, obj> > container; // prepopulated container

// insert some new obj's. Create a new sub map if key i is not found in container, 
// append to existing sub map otherwise
for(int i = 0; i < n; ++i) {
    for(int j = 0; j < m; ++j) {
        std::map<int, std::map<int, obj> >::iterator found = container.find(i);
        obj newobj = get_some_random_obj(i,j);
        std::pair<int, obj> newpair(j, newobj);
        if(found != container.end()) {
            found->second.insert(newpair);
        } else {
            std::map<int, obj> newmap;
            newmap.insert(newpair);
            container.insert(std::make_pair(i, newmap));
        }
    }
}

Two questions:

Thank you for your help!

Upvotes: 0

Views: 1027

Answers (4)

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76828

If you use operator[] to access the elements, an empty one will be created if none exists yet (this works because std::map::value_type has to be default-constructible):

std::map<int, std::map<int, obj> > foo;
foo[i][j] = some_object;

Note that, if foo[i][j] already exists, it will be replaced by the new value.

Upvotes: 1

Chris Card
Chris Card

Reputation: 3266

std::map has an insert() function which returns a std::pair containing a boolean and an iterator.

If the boolean is true then the insert succeeded, and if the boolean is false then the key already exists and the iterator corresponds to the key so you can update the value.

Upvotes: 0

Erik
Erik

Reputation: 91270

container[i][j] = get_some_random_obj(i,j);

map's operator[] inserts if the element isn't present.

Upvotes: 4

miked
miked

Reputation: 3598

I'm not sure here, but I think the std::multimap may be what you need. It will handle multiple objects per key.

Upvotes: 0

Related Questions