如何在地图中使用带有lambda函数的tolower? C ++

时间:2015-11-26 20:49:08

标签: c++ algorithm dictionary lambda transform

我想将地图中存储的所有单词更改为小写。有了lambda函数和变换,我该怎么做?

std::map <string, int> M;
std::map<string, int> M1;

std::transform(M.begin(), M.end(), M1.begin(),
         [](pair<const string, int> const & p) { ::tolower(p.first); });

3 个答案:

答案 0 :(得分:2)

您无法在#include <iostream> #include <map> #include <algorithm> int main() { std::map<std::string, int> map = {{ "HELLO", 1 }, { "WORLD", 2 }}; std::cout << "before:\n"; for (auto& kv : map) { std::cout << '\t' << kv.first << ":" << kv.second << '\n'; } // create a new map with lowercase keys std::map<std::string, int> out; std::for_each(map.begin(), map.end(), [&](auto& kv) { std::string lower; std::transform(kv.first.begin(), kv.first.end(), std::back_inserter(lower), tolower); out[lower] = kv.second; }); std::cout << "after:\n"; for (auto& kv : out) { std::cout << '\t' << kv.first << ":" << kv.second << '\n'; } return 0; } 中修改,因此您必须创建新地图

有些事情:

  • 迭代覆盖地图中的值
  • 获取密钥的副本
  • 转换为小写
  • 插入到结果地图中:

示例:

before:
    HELLO:1
    WORLD:2
after:
    hello:1
    world:2

输出:

{
    // Is git enabled
    "git.enabled": true,

    // Path to the git executable
    "git.path": "C:\\path\\to\\git.exe"

    // other settings
}

答案 1 :(得分:1)

std::transform将仿函数的结果分配给目标范围内的元素。这意味着目标迭代器必须是与输入范围大小相同的范围的起点。在您的示例中,目标是空地图。转换本质上是以下循环:

std::map <string, int> M;
std::map<string, int> M1;

for(auto i=M.begin(), j=M1.begin(); i != M.end(); ++i,++j)
{
    *j = f(*i);
}

减少j对于空容器是非法的,并且对于地图没有意义,因为您无法更改密钥。

您可以从此代码中看到,您的lambda也不正确。它应该将一个(键值)对转换为目标类型的对象。在您的情况下,目标类型是相同的。

您必须先调整目标容器的大小,例如:通过调用resize(如果它是一个向量),或者使用一个迭代器来使赋值适应map::insert。 STL为此提供了适配器:

#include <map>
#include <string>
#include <cctype>
#include <iterator>
#include <algorithm>

int main() {
std::map <std::string, int> M;
std::map<std::string, int> M1;

std::transform(M.begin(), M.end(), std::inserter(M1, M1.begin()),
               [](std::pair<const std::string, int> const & p) 
{ 
    std::string lowercase;
    std::transform( p.first.begin(), p.first.end(), 
                    std::back_inserter(lowercase),
                    [](auto c) {return std::tolower(c);} );

    return std::make_pair(lowercase, p.second); 
});

return 0;
}

答案 2 :(得分:1)

如果您想要使用std::transform,那么您可以使用以下方法

#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include <cctype>
#include <iterator>
#include <utility>


int main ()
{
    std::map<std::string, int> m1 = { { "FIRST", 1 }, { "SECOND", 2 } };

    for ( const auto &p : m1 ) 
    {
        std::cout << p.first << '\t' << p.second << std::endl;
    }

    auto to_lower_case = []( const std::pair<const std::string, int> &p )
    {
        std::string t; t.reserve( p.first.size() );
        std::transform( p.first.begin(), p.first.end(),
                        std::back_inserter( t ), ::tolower );
        return std::make_pair( t, p.second );                        
    };

    std::cout << std::endl;

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

    std::transform( m1.begin(), m1.end(), 
                    std::inserter( m2, m2.begin() ), to_lower_case );

    for ( const auto &p : m2 ) 
    {
        std::cout << p.first << '\t' << p.second << std::endl;
    }
}

程序输出

FIRST   1
SECOND  2

first   1
second  2

在程序中,使用std::transform两次。