Home > Enterprise >  Copying string into set<string> in lowercase?
Copying string into set<string> in lowercase?

Time:11-16

I have the following small and easy code:

int main(int argc, char *argv[]) {
    std::vector<std::string> in;
    std::set<std::string> out;

    in.push_back("Hi");
    in.push_back("Dear");
    in.push_back("Buddy");

    for (const auto& item : in) {
***        std::transform(item.begin(),item.end(),item.begin(), ::tolower);
***        out.insert(item); 
    }    
    
    return 0;
}

I'd like to copy all items of in into out.

However, with an in-place lowercase conversion, preferrably without an extra temporary variable.

So this is the required content of out at the end:

hi
dear
buddy

Please note, const auto& item is fixed, meaning I can't remove the const requirement (this is part of a bigger library, here is over-simplified for demo).

How should I do this? (If I remove the "const" modifier, it works, but if modifications are not allowed on item, how can I still insert the item into the set, while also transforming it to lowercase?)

CodePudding user response:

You need a lambda function with transform, and you shouldn't have a const & to your strings or transform can't modify it.

#include <algorithm>
#include <set>
#include <string>
#include <vector>

int main() 
{
    std::vector<std::string> in;
    std::set<std::string> out;

    in.push_back("Hi");
    in.push_back("Dear");
    in.push_back("Buddy");

    for (/*const*/ auto& item : in)  // you can't have a const & if your going to modify it.
    {
        std::transform(item.begin(), item.end(), item.begin(), [](const char c) 
        { 
            return static_cast<char>(::tolower(c)); 
        });

        out.insert(item);
    }

    return 0;
}

CodePudding user response:

Note, you have to copy - since items in the original in container can not be moved into out container. The below code makes the copy of each element exactly once.

...
in.push_back("Hi");
in.push_back("Dear");
in.push_back("Buddy");

std::transform(in.begin(), in.end(), std::inserter(out, out.end()),
               [] (std::string str) { boost::algorithm::to_lower(str); return str;}
              );    
return 0;
  • Related