返回嵌套JSON中包含特定键的所有值?

时间:2015-04-07 14:27:36

标签: javascript json

我已经嵌套了JSON,如下所示:

{
    "fields": {
        "type": "custom",
        "level1": {
            "type": "custom"
        },
        "level2": {
            "type": "custom",
            "level3": {
                "type": "custom"
            },
            "level31": {
                "type": "notcustom"
            }
        }
    }
}

我想提取具有键type

的所有值

我想要的输出是:

{
    "fields":"custom",
    "level1":"custom",
    "level2":"custom"
}

2 个答案:

答案 0 :(得分:2)

我尝试使用递归方法很简单。首先检查它是否是一个对象。如果它的对象再次调用传递该对象的函数。

否则检查该键和适当的值。在结果对象中填充它并返回它。

    var object = {
      "fields": {
        "type": "custom",
        "level1": {
          "type": "custom"
        },
        "level2": {
          "type": "custom",
          "level3": {
            "type": "custom"
          },
          "level31": {
            "type": "notcustom"
          }
        }
      }
    };

    function recursiveIterator(object, needle, value, result) {
      var result = result || {};

      for (var key in object) {
        if (object[key][needle] === value) {
          result[key] = object[key][needle];
        }

        if (typeof object[key] === "object") {
          recursiveIterator(object[key], needle, value, result);
        }
      }

      return result;
    }

    document.getElementById("result").textContent = JSON.stringify(recursiveIterator(object, "type", "custom"));
<div id="result"></div>

这是一种非常通用的方法。在这种情况下,您可以传递key type以及您希望匹配的值,custom

答案 1 :(得分:0)

您需要recursive function来导航树结构。

以下代码段执行此操作,并将结果添加到自定义字段数组中。

我没有删除自定义字段的子属性,因此如果自定义字段具有子级属性,则还包含该属性。您可以删除这些子属性,但也可以修改源对象树。因此,这可以解决创建具有Object.create的克隆并在之后删除整个属性...但我相信整个代码足以让您敞开心扉并理解如何解决问题。

运行代码段以实时查看JSON结果!

更新

虽然你请求了一个对象(毕竟像是一个字典),但我建议在这种情况下,数组结果应该更好,因为如果有超过&#34;级别& #34;属性调用方式相同(例如,两个level1属性),只有最后一个属性可以在结果中访问,因为它可能会被覆盖。

&#13;
&#13;
var obj = {
    "fields": {
        "type": "custom",
            "level1": {
            "type": "custom"
        },
            "level2": {
            "type": "custom",
                "level3": {
                "type": "custom"
            },
                "level31": {
                "type": "notcustom"
            }
        }
    }
};

function getCustomFields(field, customFields) {
    var customFields = typeof customFields != "undefined" ? customFields : [];

    if (field["type"] == "custom") {
        customFields.push(field);
    }

    // Object.keys gets all own object property names as an array
    // in order to use filter to do a "where" the fieldName starts with
    // "level" word. Once every "level" property is filtered, you execute
    // an Array.forEach to execute the enclosing functin against the
    // inner level giving each level field and current customFields array
    // to accumulate results...
    Object.keys(field).filter(function (fieldName) {
        return fieldName.indexOf("level") == 0;
    }).forEach(function (levelPropertyName) {
        getCustomFields(field[levelPropertyName], customFields);
    });
    
    return customFields;
}

var customFields = getCustomFields(obj.fields);

document.getElementById("result").textContent = JSON.stringify(customFields);
&#13;
<div id="result"></div>
&#13;
&#13;
&#13;