简体   繁体   English

如何迭代STL映射中的STL映射?

[英]How can I iterate over an STL map inside an STL map?

I have an STL map definition as follows: 我有一个STL映射定义如下:

map<string, map<int, string> > info;

I iterate that map using the following code: 我使用以下代码迭代该映射:

for( map<string, map<int, string> >::iterator ii=info.begin(); ii!=info.end(); ++ii){
    for(map<int, string>::iterator j=ii->second.begin(); j!=ii->second.end();++j){
        cout << (*ii).first << " : " << (*j).first << " : "<< (*j).second << endl;
    }
}

Is this the correct way to iterate or is there a better way to do so? 这是迭代的正确方法还是有更好的方法? The above code works for me, but I'm looking for a more elegant solution. 上面的代码适合我,但我正在寻找一个更优雅的解决方案。

This is correct, it just lacks a few typedef and readability improvements : 这是正确的,它只是缺少一些typedef和可读性改进:

typedef std::map<int, std::string> inner_map;
typedef std::map<std::string, inner_map> outer_map;

for (outer_map::iterator i = outerMap.begin(), iend = outerMap.end(); i != iend; ++i)
{
    inner_map &innerMap = i->second;
    for (inner_map::iterator j = innerMap.begin(), jend = innerMap.end(); j != jend; ++j)
    {
        /* ... */
    }
}

If C++11 is available you may use range for loop: 如果C ++ 11可用,您可以使用range for循环:

for(auto &i: info) {
    for(auto &j: i.second) {
        /* */
    }
}

If only C++11 auto is available: 如果只有C ++ 11 auto可用:

for( auto i=info.begin(); i!=info.end(); ++i) {
   for( auto j=i->second.begin(); j!=i->second.end(); ++j) {
       /* */
   }
}

If you may use BOOST there is BOOST_FOREACH: 如果您可以使用BOOST,则有BOOST_FOREACH:

typedef std::map<int, std::string> inner_map;
typedef std::map<std::string, inner_map> outer_map;

outer_map outer;

BOOST_FOREACH(outer_map::value_type &outer_value, outer){
    BOOST_FOREACH(inner_map::value_type &inner_value, outer_value->second){
        /* use outer_value and inner_value as std::pair */
    }
}

If c++11 is available, we could use stl algorithm for_each and lambda functions to get a elegant solution 如果c ++ 11可用,我们可以使用stl算法for_each和lambda函数来获得一个优雅的解决方案

typedef map<int, string> INNERMAP;
typedef map<string, INNERMAP> OUTERMAP;

OUTERMAP theMapObject;
// populate the map object

// iterate the map object now //现在迭代地图对象

std::for_each(theMapObject.cbegin(), theMapObject.cend(), 
    [](const OUTERMAP::value_type& outerMapElement)
{
    // process the outer map object
    const INNERMAP& innerMapObject = outerMapElement.second;
    std::for_each(innerMapObject.cbegin(), innerMapObject.cend(), 
        [](const INNERMAP::value_type& innermapElemen)
    {
        //process the inner map element
    });
});

While it's not clear what problem you are solving by having a map inside a map, I don't think there is a better way of iterating on all the items without using these iterators. 虽然通过在地图中使用地图来解决您正在解决的问题尚不清楚,但我认为没有使用这些迭代器可以更好地迭代所有项目。 The only thing you can do to improve code readability is to use typedefs on the template types. 要提高代码可读性,唯一可以做的就是在模板类型上使用typedef。

However, won't it be a better idea to define your map as 但是,将map定义为不是更好的主意

multimap <string, MyClass>

where MyClass is defined as a pair of integer and a string, as well as a toString() method to dump the contents, etc? 其中MyClass被定义为一对整数和一个字符串,以及转储内容的toString()方法等?

If you want to iterate through both maps, then the way you presented is the best way. 如果你想遍历两个地图,那么你提出的方式是最好的方式。 Now, if there is something specific you want to do then you might be better with using a function from the algorithm header. 现在,如果您想要做某些特定事情,那么使用算法标题中的函数可能会更好。

If you have access to C++11 features, then range-based for loops as proposed in Juraj Blaho's answer seem to be the most readable option to me. 如果您可以访问C ++ 11的功能,那么Juraj Blaho的答案中提出的基于范围的for循环对我来说似乎是最具可读性的选项。 However, if C++17 is available to you, then you can use structured bindings together with those loops to further increase readability, as you can get rid of all first and second members: 但是,如果你可以使用C ++ 17 ,那么你可以使用结构化绑定和这些循环来进一步提高可读性,因为你可以摆脱所有firstsecond成员:

std::map<std::string, std::map<int, std::string>> info;

for (const auto &[k1, v1] : info) {
    for (const auto &[k2, v2] : v1) {
        std::cout << k1 << " : " << k2 << " : " << v2 << std::endl;
    }
}

Code on Coliru Coliru代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM