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

如何使用排除键数组实现JSON扁平化?

实现带排除键的JSON扁平化方案

嘿,这个需求很实用!我们可以通过在扁平化递归过程中,实时检查当前键的完整路径是否匹配排除规则,来精准跳过指定的层级键。下面是修改后的完整代码,包含详细的功能实现和注释:

// 可配置的排除键数组,支持层级路径(如"addresses.metadata")或顶层键(如"metadata")
var exclusion_list = ["addresses.metadata", "pageToken", "metadata"];
var crowds = [{
    "name": [{
        "firstName": "John",
        "middleName": "Joseph",
        "lastName": "Briggs",
    }],
    "addresses": [{
        "type": "home",
        "poBox": "111",
        "city": "City1",
        "postalCode": "1ER001",
        "country": "USA",
        "metadata": "要排除的地址元数据" // 这个会被排除
    }, {
        "type": "work",
        "poBox": "222",
        "city": "City2",
        "region": "Region2",
        "postalCode": "1ER002",
    }],
    "photos": [{
        "url": "photo.org/person1",
        "default": true,
    }, {
        "url": "imagur.org/person1",
        "default": true,
    }],
    "metadata": [{
        "meta-id": "1234", // 顶层metadata会被排除
    }],
}, {
    "name": [{
        "firstName": "Bill",
        "lastName": "Thatcher",
    }],
    "addresses": [{
        "type": "home",
        "city": "City3",
        "region": "Region3",
        "postalCode": "1ER003",
        "country": "USA",
    }, {
        "type": "work",
        "poBox": "444",
        "region": "Region4",
        "postalCode": "1ER004",
        "metadata": "另一个要排除的地址元数据" // 这个也会被排除
    }, {
        "poBox": "555",
        "region": "Region5",
        "postalCode": "1ER005",
    }],
    "metadata": [{
        "meta-id": "1234", // 顶层metadata会被排除
    }],
}];

// 辅助函数:检查当前路径是否需要排除
function shouldExclude(currentKeyPath, exclusionList) {
    // 1. 把扁平化生成的路径格式(如"addresses #1: metadata")转换成标准层级格式("addresses.metadata")
    const normalizedPath = currentKeyPath
        .replace(/: /g, '.') // 把": "替换成"."
        .replace(/ #\d+/g, ''); // 去掉数组项的索引标记(如" #1")
    
    // 2. 检查是否匹配排除列表中的任意规则
    return exclusionList.some(excludeRule => {
        // 排除规则支持精确层级匹配,比如"addresses.metadata"仅匹配addresses节点下的metadata
        return normalizedPath === excludeRule;
    });
}

// 带排除功能的扁平化函数
function flatten(obj, exclusionList, res = {}, currentKey = '') {
    const addKeyPart = (delimiter, part) => currentKey ? `${currentKey}${delimiter}${part}` : part;

    if (Array.isArray(obj)) {
        // 处理数组:给每个项添加索引标记(如" #1")
        obj.forEach((item, index) => {
            const newKey = addKeyPart(' #', index + 1);
            flatten(item, exclusionList, res, newKey);
        });
    } else if (typeof obj === 'object' && obj !== null) {
        // 处理对象:遍历每个键值对
        Object.entries(obj).forEach(([key, value]) => {
            const newKey = addKeyPart(': ', key);
            // 检查当前键路径是否需要排除,不需要才继续处理
            if (!shouldExclude(newKey, exclusionList)) {
                flatten(value, exclusionList, res, newKey);
            }
        });
    } else {
        // 处理基础类型:添加到结果对象
        res[currentKey] = obj;
    }
    return res;
}

// 生成扁平化后的数组
let flats = crowds.map(obj => flatten(obj, exclusion_list));

// 合并所有扁平化结果的键,生成表头
function combineKeys(objs) {
    let keys = objs.reduce((allKeys, obj) => allKeys.concat(Object.keys(obj)), []);
    return [...new Set(keys)]; // 去重
}

let keys = combineKeys(flats);

// 生成二维表格数组
let table = flats.map(flatObj => keys.map(key => flatObj[key] ?? ''));
table.unshift(keys); // 添加表头

console.log({ table });

关键功能说明

  • 排除规则的匹配逻辑

    • 通过shouldExclude函数,把扁平化过程中生成的路径(比如addresses #1: metadata)转换成和排除规则一致的格式(addresses.metadata),再进行精确匹配。
    • 支持两种排除规则:
      • 顶层键:比如"metadata",会跳过所有顶层的metadata节点。
      • 层级键:比如"addresses.metadata",仅跳过addresses节点下的所有metadata子节点(不管是数组中的哪一项)。
  • 扁平化函数的改动

    • 新增exclusionList参数,让排除规则可以灵活配置。
    • 在处理对象的键值对时,先检查当前路径是否需要排除,只有不需要排除的键才会继续递归处理。
  • 保持原有功能

    • 保留了原代码中数组项的索引标记(如name #1: firstName),确保数组展开后的结构清晰。
    • 依然会生成包含表头的二维数组,适配动态JSON转表格的需求。

内容的提问来源于stack exchange,提问作者Code Guy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 06:07:41