【问题标题】:Is there a way to iterate over the second element of a std::map? [duplicate]有没有办法遍历 std::map 的第二个元素? [复制]
【发布时间】:2021-12-28 22:35:42
【问题描述】:

我想创建一个 std::vector<char> 类似: v(map.begin(), map.end());,而不是遍历地图的所有元素并一遍又一遍地调整 v 的大小。

#include<iostream>
#include<map>
#include<vector>

int main() {
        std::map<int, char> map{{1,'a'},{2,'b'},{3,'c'}, {4,'d'}};
        std::vector<char> v;
        for(auto& [ i , c ] : map){
            // std::cout << i << " -> " << c <<"\n";
            v.push_back(c);
        }
}

【问题讨论】:

  • 如果您不想调整大小,为什么不直接使用reserve()
  • std::transform(map.begin(), map.end(), std::back_inserter(v), [](auto const&amp; pr){ return pr.second; });

标签: c++


【解决方案1】:

在 C++20 中,您可以使用 std::views::values 创建值的视图:

#include <map>
#include <vector>
#include <ranges>

int main() {
    std::map<int, char> map{{1, 'a'}, {2, 'b'}, {3, 'c'}, {4, 'd'}};    
    auto view = std::views::values(map);
    std::vector<char> v(view.begin(), view.end());
}

Demo

更通用的视图是std::views::transform,您可以在其中提供要通过函子完成的转换:

#include <map>
#include <vector>
#include <ranges>

int main() {
    std::map<int, char> map{{1, 'a'}, {2, 'b'}, {3, 'c'}, {4, 'd'}};    
    auto view = map | std::views::transform([](auto&& p){ return p.second; });
    std::vector<char> v(view.begin(), view.end());
}

Demo

【讨论】:

  • 上帝,我希望我可以在工作中使用C++20...
  • @WBuck 只是偷偷地将它添加到您的构建系统中。谁会知道?只是一个小标志...
  • std::views::values 会更干净。
  • @cigien 哦,是的。谢谢!我刚刚迈出了我的第一步,但我错过了 - 但我现在将其添加到答案中。
【解决方案2】:

您可以在std::vector 上调用reserve,以便预先分配您需要的内存并避免调整大小。

#include <map>
#include <vector>
#include <algorithm>

int main( )
{
    std::map<int, char> map{{1,'a'},{2,'b'},{3,'c'}, {4,'d'}};
    std::vector<char> v{ };
    v.reserve( map.size( ) );

    std::for_each( std::begin( map ), std::end( map ), 
        [ &v ]( const auto& pair ){ v.push_back( pair.second ); } );
}

【讨论】:

    【解决方案3】:

    如 cmets 中所述,您可以为您的向量提供reserve 空间以避免重新分配。使用 C++ 的 for 循环现在用于破坏地图之类的东西的工具,这非常干净。

    #include<iostream>
    #include<map>
    #include<vector>
    
    int main() {
        std::map<int, char> map{{1,'a'},{2,'b'},{3,'c'}, {4,'d'}};
        std::vector<char> v;
        
        v.reserve(map.size());
     
        for (auto& [i, c] : map) v.push_back(c);
        for (auto& i : v) std::cout << i << std::endl;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-06-18
      • 2010-09-14
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      相关资源
      最近更新 更多