Reputation: 40345
I get some strange behavior when inserting values into a map: I always insert at the end of the map, but sometimes the entries get out of order.
If I do a straight forward test, then I get no problems- the numbers are correctly ordered:
map<int,int> testMap;
for(int i = 0; i < 100; ++i)
{
// everything is ordered correctly here
testMap.insert(testMap.end(), pair<int,int>(i,i));
}
But when I parse a string and I try to insert the values in the same order as I read them, then things don't work out that well:
const string INPUT_TWO =
"=VAR STRING1 \"MYSTRING\"\n\
=VAR STRING2 \"EXAMPLE\"\n\
=VAR NUMBER1 12345\n\
=VAR NUMBER2 23456\n\
=VAR DUMMY 1111\n";
const string VAL_STRING = "VAR";
vector<pair<string, string>> parse_fields(const string & input)
{
map<string, string> fieldsMap;
vector<pair<string, string>> sequenceFields;
vector<string> lines = split(input, '\n');
for(size_t i = 0; i < lines.size(); ++i)
{
if(lines[i].find(VAL_STRING)!=string::npos)
{
vector<string> vals = split(lines[i], ' ');
if(vals.size()==3)
{
fieldsMap.insert(fieldsMap.end(), pair<string,string>(vals[1], remove_quotes(vals[2])));
sequenceFields.push_back(pair<string,string>(vals[1], remove_quotes(vals[2])));
}
}
}
// at the end the map looks like:
// "DUMMY", "1111"
// "NUMBER1", "12345"
// "NUMBER2", "23456"
// "STRING1", "MYSTRING"
// "STRING2", "EXAMPLE"
// the vector of pairs looks like:
// "STRING1", "MYSTRING"
// "STRING2", "EXAMPLE"
// "NUMBER1", "12345"
// "NUMBER2", "23456"
// "DUMMY", "1111"
return sequenceFields;
}
For your reference, I have pasted all the additional code in a pastie.
Does anybody know why this may be happening?
Upvotes: 3
Views: 2071
Reputation: 98459
Maps are not inherently ordered. Conceptually, they represent key-value pairs. But C++ std::map
maps are internally ordered. See http://www.cplusplus.com/reference/stl/map/ . So entries will effectively be sorted by key values.
If you need your own ordering, you should use a list of tuples. Or an unordered_map
, if you have one (see http://en.wikipedia.org/wiki/Unordered_map_%28C%2B%2B%29 ; hash_map
is probably available on your platform). Or sort the results as you retrieve them.
Upvotes: 1
Reputation: 503805
A std::map
is an ordered container, this is what allows it the look-up times it has. If you need both the mapping and listing, consider using Boost.MultiIndex.
Upvotes: 4