如何在 STL 映射内迭代 STL 映射?

发布于 2024-10-08 21:13:21 字数 518 浏览 3 评论 0原文

我有一个 STL 映射定义如下:

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

我使用以下代码迭代该映射:

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;
    }
}

这是正确的迭代方法还是有更好的方法?上面的代码对我有用,但我正在寻找更优雅的解决方案。

I have an STL map definition as follows:

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

故乡的云 2024-10-15 21:13:21

这是正确的,它只是缺少一些 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)
    {
        /* ... */
    }
}

This is correct, it just lacks a few typedef and readability improvements :

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)
    {
        /* ... */
    }
}
献世佛 2024-10-15 21:13:21

如果 C++11 可用,您可以使用范围 for 循环:

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

如果仅 C++11 auto 可用:

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

如果您可以使用 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 you may use range for loop:

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

If only C++11 auto is available:

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:

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 */
    }
}
静谧幽蓝 2024-10-15 21:13:21

虽然不清楚通过在地图中放置地图来解决什么问题,但我认为没有更好的方法可以在不使用这些迭代器的情况下迭代所有项目。提高代码可读性的唯一方法是在模板类型上使用 typedef。

不是更好吗

但是,将 map 定义为multimap

其中 MyClass 定义为一对 整数和字符串,以及转储内容的 toString() 方法等?

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.

However, won't it be a better idea to define your map as

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?

老子叫无熙 2024-10-15 21:13:21

如果c++11可用,我们可以使用stl算法for_each和lambda函数来获得一个优雅的解决方案

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

OUTERMAP theMapObject;
// populate the map object

// 现在迭代map对象

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
    });
});

If c++11 is available, we could use stl algorithm for_each and lambda functions to get a elegant solution

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
    });
});
木格 2024-10-15 21:13:21

如果您想迭代这两个地图,那么您呈现的方式是最好的方式。现在,如果您想做一些特定的事情,那么使用算法头中的函数可能会更好。

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.

乜一 2024-10-15 21:13:21

如果您有权访问 C++11 功能,则 基于范围的 for 循环,如 Juraj Blaho 的答案对我来说似乎是最可读的选项。但是,如果您可以使用 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;
    }
}

代码关于科利鲁

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. 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:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文