您已经知道如何对std::string 执行替换操作。没有什么能阻止你对容器做同样的事情(基于容器包含字符串,这里就是这种情况)。
因此,对于std::map<std::string, std::vector<std::string>>,您只需遍历地图,然后遍历向量,然后以您想要的方式替换值。
但是,由于您不仅要对映射的值执行替换,还要对键执行替换,因此变得更加棘手。
如您所知,您无法修改地图中的键。所以你有两个解决方案,你可以:
- 在地图中创建新元素 {key, value},然后删除旧元素
- 创建新地图并覆盖原来的地图
我认为第二种解决方案是最容易实现的。
可能的实施:
我们想要的是一个函数,它可以引用地图并对其进行替换。
为了实现,我决定采用上述第二个解决方案(用新创建的覆盖地图)。
我这里选择的策略是:
- 将流程分解为多个函数并将机制隐藏在包装类中。
- 由于我们不需要此类的实例来运行进程,因此我们将函数标记为
static。
- 只有所需的函数(供用户使用)将是
public,因此可以在类外访问/调用。
这会给我们:
using MyMap = std::map<std::string, std::vector<std::string>>; // For readability purposes
class e2E
{
private:
// Get a replaced version of the given string
static std::string e2E_str(const std::string & s);
// Get a replaced version of the given map
static MyMap e2E_MyMap(const MyMap & m);
public:
// Compute the replacements over the map
static void compute(MyMap & m);
};
e2E_str() 函数只是替换 std::string 的一个实现。
e2E_MyMap() 函数是生成新地图的过程的实现。
compute() 函数只是覆盖的实现(设计简单)。
然后我们得到:
std::string e2E::e2E_str(const std::string & s)
{
std::string r(s);
std::replace(r.begin(), r.end(), 'e', 'E');
return r;
}
MyMap e2E::e2E_MyMap(const MyMap & m)
{
MyMap result;
std::string key;
for(const auto & [k, v] : m)
{
key = e2E_str(k);
result[key] = {};
for(const std::string & s : v)
result[key].push_back(e2E_str(s));
}
return result;
}
void e2E::compute(MyMap & m)
{
m = e2E_MyMap(m);
}
测试:
为了便于阅读,我们可以定义一个display() 函数来显示地图。
它可能看起来像:
void display(const MyMap & m, std::ostream & os)
{
for(const auto & [k, v] : m)
{
os << k << ":\n";
for(const std::string & s : v)
os << " " << s << '\n';
}
os << std::endl;
}
然后我们可以如下调用我们的替换函数:
int main()
{
// Create the map
MyMap my_map {{"test1", {"There", "That", "Word", "The"}}, {"test2", {"This", "Where"}}};
// Display the map contents before the replacement operation
display(my_map, std::cout);
// Perform the replacements
e2E::compute(my_map);
// Display the map contents after the replacement operation
display(my_map, std::cout);
return 0;
}
如果您想快速执行并检查此测试的结果click here。