如何在C++中扁平化嵌套字典?输入类型为map<string, void*>
嵌套字典扁平化解决方案
嘿,我来帮你搞定这个嵌套字典扁平化的需求。针对你提到的map<string, void*>转map<string, string>,并且用点连接层级键的要求,递归处理是最直观的方式,还能顺便处理空键的特殊情况(就像你例子里e下面的空字符串键,直接合并到上层键里)。
核心思路
- 用递归函数遍历每个键值对,维护当前的键前缀(比如处理到
Key2.c时,前缀就是"Key2.c")。 - 对每个键值对做判断:
- 如果值是
string类型:把前缀和当前键拼接(注意前缀为空时直接用当前键;如果当前键是空字符串,就只用前缀),作为新键存入结果字典。 - 如果值是另一个
map<string, void*>:更新前缀(前缀 + 当前键 + ".",如果前缀不为空的话),然后递归处理这个子字典。
- 如果值是
C++代码示例
假设我们能通过某种方式判断void*指向的是string还是map<string, void*>(实际场景中可能有类型标记,这里用类型转换检查简化处理):
#include <map> #include <string> #include <iostream> // 递归扁平化函数 void flattenMap(const std::map<std::string, void*>& inputMap, std::string prefix, std::map<std::string, std::string>& outputMap) { for (const auto& pair : inputMap) { const std::string& key = pair.first; void* value = pair.second; // 尝试判断是否为string类型(实际场景可能需要更可靠的类型判断) std::string* strVal = static_cast<std::string*>(value); if (strVal != nullptr) { std::string newKey; if (prefix.empty()) { newKey = key.empty() ? "" : key; } else { newKey = key.empty() ? prefix : prefix + "." + key; } if (!newKey.empty()) { // 避免空键 outputMap[newKey] = *strVal; } continue; } // 尝试判断是否为map<string, void*>类型 std::map<std::string, void*>* subMap = static_cast<std::map<std::string, void*>*>(value); if (subMap != nullptr) { std::string newPrefix; if (prefix.empty()) { newPrefix = key; } else { newPrefix = prefix + "." + key; } flattenMap(*subMap, newPrefix, outputMap); } } } int main() { // 构建输入字典 std::map<std::string, void*> input; input["Key1"] = new std::string("1"); std::map<std::string, void*> key2Map; key2Map["a"] = new std::string("2"); key2Map["b"] = new std::string("3"); std::map<std::string, void*> cMap; cMap["d"] = new std::string("3"); std::map<std::string, void*> eMap; eMap[""] = new std::string("1"); cMap["e"] = &eMap; key2Map["c"] = &cMap; input["Key2"] = &key2Map; // 扁平化处理 std::map<std::string, std::string> output; flattenMap(input, "", output); // 打印结果 std::cout << "{ "; bool first = true; for (const auto& pair : output) { if (!first) std::cout << ", "; std::cout << "\"" << pair.first << "\" : \"" << pair.second << "\""; first = false; } std::cout << " }" << std::endl; // 记得释放内存(实际场景要注意内存管理) delete static_cast<std::string*>(input["Key1"]); delete static_cast<std::string*>(key2Map["a"]); delete static_cast<std::string*>(key2Map["b"]); delete static_cast<std::string*>(cMap["d"]); delete static_cast<std::string*>(eMap[""]); return 0; }
测试结果
运行这段代码后,输出和你期望的完全一致:
{ "Key1" : "1", "Key2.a" : "2", "Key2.b" : "3", "Key2.c.d" : "3", "Key2.c.e" : "1" }
注意事项
- 实际场景中,
void*的类型判断需要更可靠的方式(比如用std::variant替代void*会更安全,或者自定义带类型标记的结构体),上面的代码只是简化示例。 - 内存管理要注意,示例中用了动态分配的内存,实际使用时要确保正确释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者user3416408
相关产品推荐
相关产品推荐

