1

How to iterate through a std::map<string,int> and std::vector<int> using single for loop ?

I have seen this questions but could not solve my problem.

I am trying like this

map<string,int> data;
data["Shravan"] = 1;
data["Mama"] = 2;
data["Sa1"] = 3;
data["Jhandu"] = 4;

vector<int> values = {1,2,3,4};

for(const auto& it1: data,it2 : values) {
    // Do something 
}

Edit : I can not go through one by one. Because i am using the key of std::map and value of std::vector in the same function. Which will be called inside for loop.

Both the container of same size.

Community
  • 1
  • 1
Shravan40
  • 6,849
  • 5
  • 21
  • 43
  • Why?? And what behaviour do you want; go through one container then the other? Or can they be interleaved? – BoBTFish Feb 10 '17 at 07:50
  • have a look at http://www.cplusplus.com/reference/map/map/begin/ and http://www.cplusplus.com/reference/map/map/end/ , but it is to be noted, that this is not a good practice... Similar functionality also applies to vectors – Kupto Feb 10 '17 at 07:52
  • @BoBTFish : I can not go through one by one. Because i am using the key of `std::map` and value of `std::vector` in the same function. – Shravan40 Feb 10 '17 at 07:54
  • There are may good answers, I wish i could accept all. But I have to obey the SO rules, hence accepting one. – Shravan40 Feb 10 '17 at 08:56

4 Answers4

3

If you know there's both the same length, use something like:

auto vit = begin(value);
auto mit = begin(data);
for (; vit != end(value); ++mit, ++vit) {
    // Use mit and vit
}
Paul Evans
  • 26,111
  • 3
  • 30
  • 50
2

How about a do-while? Provided that your containers aren't empty.

auto iv = std::begin(value);
auto id = std::begin(data);

do {
    // Use those iterators
} while(++iv != std::end(value) && ++id != std::end(data))

Or use while if you'd like to handle empty containers too.

auto iv = std::begin(value);
auto id = std::begin(data);

while(iv != std::end(value) && id != std::end(data)) {
    // Use those iterators

    iv++; id++;
}
frogatto
  • 26,401
  • 10
  • 73
  • 111
1

Consider boost::zip_iterator discussed in this answer https://stackoverflow.com/a/8513803/2210478

Community
  • 1
  • 1
Chen OT
  • 2,945
  • 2
  • 19
  • 38
  • @MikeMB Yes, you're right. The code I suggested is wrong. I've removed it. Maybe OP can check the zip_iterator still. – Chen OT Feb 10 '17 at 08:03
  • 1
    Ok, removed the down vote. If you add a usage example you get an upvote. – MikeMB Feb 10 '17 at 08:07
1

You can iterate over both the map and the vector and make sure to check the iterators against the end of the corresponding container.

auto map_iter = data.begin();
auto vec_iter = value.begin();
for (; map_iter != data.end() && vec_iter != value.end();
       ++map_iter, ++vec_iter) {
    // Use map_iter and vec_iter
}
R Sahu
  • 196,807
  • 13
  • 136
  • 247