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

如何编写JavaScript递归函数在嵌套对象中按键值查找?

递归搜索嵌套对象的键值对问题

我尝试编写递归函数,用来在嵌套对象中按键和值搜索,但始终无法实现,试过多个示例都不行,求帮忙解决。

我的目标对象如下:

var menuObj = {
    "mainmenu": [
        {
            "id" : 72,
            "menu_id" :1 ,
            "parent_id" : 0,
            "href" : "{\"routeName\":\"post-page\",\"routeParams\":{\"slug\":\"algemene-voorwaarden\"}}",
            "permission" : null,
            "hierarchie" : 0,
            "blank" : 0,
            "status" : "published",
            "label" : "Algemene Voorwaarden",
            "children":[]
        },
        {
            "id" : 73,
            "menu_id" : 1,
            "parent_id" : 0,
            "href" : "{\"routeName\":\"post-page\",\"routeParams\":{\"slug\":\"privacy\"}}",
            "permission" : null,
            "hierarchie" : 1,
            "blank" : 0,
            "status" : "published",
            "label" : "Privacy",
            "children" : [
                {
                    "id" : 101,
                    "menu_id" : 1,
                    "parent_id" : 73,
                    "href" : "{\"routeName\":\"blog\"}",
                    "permission" : null,
                    "hierarchie" : 2,
                    "blank" : 0,
                    "status" : "published",
                    "label" : "blog",
                    "children" : [
                        {
                            "id" : 102,
                            "menu_id" : 1,
                            "parent_id" : 101,
                            "href" : "{\"routeName\":\"blog\",\"routeParams\":{\"category_slug\":\"categorie-2\"}}",
                            "permission" : null,
                            "hierarchie" : 3,
                            "blank" : 0,
                            "status" : "published",
                            "label" : "Categorie 2",
                            "children" : []
                        }
                    ]
                }
            ]
        }
    ]
};

我需要一个这样的函数:

function fnFindKeyValuePair(obj, key, value) {
    // 返回true/false/null/undefined 或者匹配的对象
}

搜索示例:

fnFindKeyValuePair(menuObj['mainmenu'], 'href', "{\"routeName\":\"blog\"}")

预期结果:返回真值或者对应的匹配对象:

{
    "id" : 101,
    "menu_id" : 1,
    "parent_id" : 73,
    "href" : "{\"routeName\":\"blog\"}",
    "permission" : null,
    "hierarchie" : 2,
    "blank" : 0,
    "status" : "published",
    "label" : "blog",
    "children" : [
        {
            "id" : 102,
            "menu_id" : 1,
            "parent_id" : 101,
            "href" : "{\"routeName\":\"blog\",\"routeParams\":{\"category_slug\":\"categorie-2\"}}",
            "permission" : null,
            "hierarchie" : 3,
            "blank" : 0,
            "status" : "published",
            "label" : "Categorie 2",
            "children" : []
        }
    ]
}

解决方案

以下是可以实现需求的递归函数,支持数组和对象的嵌套结构,找到匹配项后立即返回:

function fnFindKeyValuePair(obj, key, value) {
    // 处理数组:遍历每个元素递归搜索
    if (Array.isArray(obj)) {
        for (const item of obj) {
            const result = fnFindKeyValuePair(item, key, value);
            if (result) return result;
        }
        return null;
    }

    // 处理对象:先检查当前对象是否匹配
    if (typeof obj === 'object' && obj !== null) {
        if (obj[key] === value) return obj;

        // 遍历对象属性,递归搜索嵌套结构
        for (const prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                const result = fnFindKeyValuePair(obj[prop], key, value);
                if (result) return result;
            }
        }
    }

    // 非对象/数组或未找到匹配项
    return null;
}

函数说明:

  • 优先处理数组输入,遍历数组元素逐个递归搜索
  • 若输入是对象,先检查当前对象的目标键值是否匹配,匹配则直接返回当前对象
  • 当前对象不匹配时,遍历其所有自有属性,递归搜索嵌套的对象或数组
  • 未找到匹配项时返回null

使用验证:

执行以下代码即可得到预期结果:

const matchedObj = fnFindKeyValuePair(menuObj['mainmenu'], 'href', "{\"routeName\":\"blog\"}");
console.log(matchedObj);

额外优化(针对JSON字符串匹配):

如果href这类字段是JSON字符串,建议解析成对象后再比较,避免因字符串格式细节(如空格、转义差异)导致匹配失败。优化后的函数如下:

function fnFindKeyValuePair(obj, key, value, parseJson = false) {
    if (Array.isArray(obj)) {
        for (const item of obj) {
            const result = fnFindKeyValuePair(item, key, value, parseJson);
            if (result) return result;
        }
        return null;
    }

    if (typeof obj === 'object' && obj !== null) {
        let currentVal = obj[key];
        let targetVal = value;

        // 开启JSON解析时,尝试解析字符串为对象
        if (parseJson && typeof currentVal === 'string' && typeof targetVal === 'string') {
            try {
                currentVal = JSON.parse(currentVal);
                targetVal = JSON.parse(targetVal);
            } catch (e) {
                // 解析失败则保留原字符串比较
            }
        }

        // 使用JSON.stringify统一比较对象或字符串
        if (JSON.stringify(currentVal) === JSON.stringify(targetVal)) {
            return obj;
        }

        for (const prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                const result = fnFindKeyValuePair(obj[prop], key, value, parseJson);
                if (result) return result;
            }
        }
    }

    return null;
}

使用优化版函数时,传入true开启JSON解析匹配:

const matchedObj = fnFindKeyValuePair(menuObj['mainmenu'], 'href', '{"routeName":"blog"}', true);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 20:44:55