简体   繁体   English

如何从嵌套对象获取键值

[英]How to get the key value from nested object

I am having below object where I am trying to get all the id values. 我在下面的对象中试图获取所有id值。

[{
    "type": "test",
    "id": "100",
    "values": {
        "name": "Alpha"
    },
    "validations": []
}, {
    "type": "services",
    "validations": [{
        "id": "200",
        "name": "John",
        "selection": [{
            "id": "300",
            "values": {
                "name": "Blob"
            }
        }]
    }]
}]

Using the below code, I am getting only the first id value. 使用以下代码,我仅获得第一个id值。 Is there any way to get all the id values from the nested object without using any external module. 有没有办法从嵌套对象中获取所有id值,而无需使用任何外部模块。

for (var prop in obj) {
            console.log(prop)
            if (prop === key) {
                set.push(prop);
            }
        }

Expected Output 预期产量

[100,200,300]     //all id values

You can use a JavaScript function like below to get the nested properties: 您可以使用如下所示的JavaScript函数来获取嵌套属性:

function findProp(obj, key, out) {
    var i,
        proto = Object.prototype,
        ts = proto.toString,
        hasOwn = proto.hasOwnProperty.bind(obj);

    if ('[object Array]' !== ts.call(out)) out = [];

    for (i in obj) {
        if (hasOwn(i)) {
            if (i === key) {
                out.push(obj[i]);
            } else if ('[object Array]' === ts.call(obj[i]) || '[object Object]' === ts.call(obj[i])) {
                findProp(obj[i], key, out);
            }
        }
    }

    return out;
}

Check this Fiddle for a working solution. 检查此小提琴以获取可行的解决方案。

Using Object.keys 使用Object.keys

 function findProp(obj, prop) { var result = []; function recursivelyFindProp(o, keyToBeFound) { Object.keys(o).forEach(function (key) { if (typeof o[key] === 'object') { recursivelyFindProp(o[key], keyToBeFound); } else { if (key === keyToBeFound) result.push(o[key]); } }); } recursivelyFindProp(obj, prop); return result; } // Testing: var arr = [{ "type": "test", "id": "100", "values": { "name": "Alpha" }, "validations": [] }, { "type": "services", "validations": [{ "id": "200", "name": "John", "selection": [{ "id": "300", "values": { "name": "Blob" } }] }] }]; console.log(findProp(arr, "id")); 

To get the keys from nested objects, you first need to put your code in a function, then for each of the top-level keys, check if it's an array or object. 要从嵌套对象中获取键,首先需要将代码放入函数中,然后对于每个顶级键,检查它是数组还是对象。 If it is, just call your function again from within that function (weird, I know.) Just make sure you don't skip the check of whether it's an object. 如果是这样,只需从该函数中再次调用该函数即可(我知道这很奇怪。)请确保不要跳过对是否为对象的检查。 You'll get stuck in an infinite loop. 您将陷入无限循环。 Something like this: 像这样:

function parseObjectKeys(obj) {
  for (var prop in obj) {
    console.log(prop)
    var sub = obj[prop]
    if (typeof(sub) == "object") {
      parseObjectKeys(sub);
    }
  }
}

Here's a more complex example: https://jsfiddle.net/tfqLnzLm/1/ 这是一个更复杂的示例: https : //jsfiddle.net/tfqLnzLm/1/

You can use a XPath styled json parser like JSONPath . 您可以使用XPath风格的json解析器,例如JSONPath The version I'm presenting here is a extended version I did here : 我在这里介绍的版本是一个扩展版本我没有在这里

 function jsonPath(obj,expr,arg){var P={resultType:arg&&arg.resultType||"VALUE",result:[],normalize:function(e){var t=[];return e.replace(/[\\['](\\??\\(.*?\\))[\\]']/g,function(e,r){return"[#"+(t.push(r)-1)+"]"}).replace(/'?\\.'?|\\['?/g,";").replace(/;;;|;;/g,";..;").replace(/;$|'?\\]|'$/g,"").replace(/#([0-9]+)/g,function(e,r){return t[r]})},asPath:function(e){for(var t=e.split(";"),r="$",a=1,n=t.length;n>a;a++)r+=/^[0-9*]+$/.test(t[a])?"["+t[a]+"]":"['"+t[a]+"']";return r},store:function(e,t){return e&&(P.result[P.result.length]="PATH"==P.resultType?P.asPath(e):t),!!e},trace:function(e,t,r){if(e){var a=e.split(";"),n=a.shift();if(a=a.join(";"),t&&t.hasOwnProperty(n))P.trace(a,t[n],r+";"+n);else if("*"===n)P.walk(n,a,t,r,function(e,t,r,a,n){P.trace(e+";"+r,a,n)});else if(".."===n)P.trace(a,t,r),P.walk(n,a,t,r,function(e,t,r,a,n){"object"==typeof a[e]&&P.trace("..;"+r,a[e],n+";"+e)});else if(/,/.test(n))for(var l=n.split(/'?,'?/),s=0,c=l.length;c>s;s++)P.trace(l[s]+";"+a,t,r);else/^\\(.*?\\)$/.test(n)?P.trace(P.eval(n,t,r.substr(r.lastIndexOf(";")+1))+";"+a,t,r):/^\\?\\(.*?\\)$/.test(n)?P.walk(n,a,t,r,function(e,t,r,a,n){P.eval(t.replace(/^\\?\\((.*?)\\)$/,"$1"),a[e],e)&&P.trace(e+";"+r,a,n)}):/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(n)&&P.slice(n,a,t,r)}else P.store(r,t)},walk:function(e,t,r,a,n){if(r instanceof Array)for(var l=0,s=r.length;s>l;l++)l in r&&n(l,e,t,r,a);else if("object"==typeof r)for(var c in r)r.hasOwnProperty(c)&&n(c,e,t,r,a)},slice:function(e,t,r,a){if(r instanceof Array){var n=r.length,l=0,s=n,c=1;e.replace(/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/g,function(e,t,r,a){l=parseInt(t||l),s=parseInt(r||s),c=parseInt(a||c)}),l=0>l?Math.max(0,l+n):Math.min(n,l),s=0>s?Math.max(0,s+n):Math.min(n,s);for(var o=l;s>o;o+=c)P.trace(o+";"+t,r,a)}},eval:function(x,_v,_vname){try{return $&&_v&&eval(x.replace(/@/g,"_v"))}catch(e){throw new SyntaxError("jsonPath: "+e.message+": "+x.replace(/@/g,"_v").replace(/\\^/g,"_a"))}}},$=obj;return expr&&obj&&("VALUE"==P.resultType||"PATH"==P.resultType)?(P.trace(P.normalize(expr).replace(/^\\$;/,""),obj,"$"),P.result.length?P.result:!1):void 0} // some extensions I have added to JSONPath var jsonPathStore = function(obj,path,values) { var maps=jsonPath(obj, path,{resultType:"PATH"}) maps.map(function(item,index) { return eval( '(' + item.replace(/\\$/,"obj") + '="' + values[index] +'"' + ')' ); }) } var jsonPathDelete = function(obj,path) { var maps=jsonPath(obj, path,{resultType:"PATH"}) maps.map(function(item,index) { return eval( '(' + 'delete ' + item.replace(/\\$/,"obj") + ')' ); }) } var jsonPathRead = function(obj,path) { var maps=jsonPath(obj, path,{resultType:"PATH"}) return maps.map(function(item,index) { return eval( '(' + item.replace(/\\$/,"obj") + ')' ); }) } var jsonObject = [{ "type": "test", "id": "100", "values": { "name": "Alpha" }, "validations": [] }, { "type": "services", "validations": [{ "id": "200", "name": "John", "selection": [{ "id": "300", "values": { "name": "Blob" } }] }] }] // this XPath will read all the id properties starting from the root element console.log( "jsonPathRead All Ids" + JSON.stringify(jsonPathRead(jsonObject,"$..id"), null, 2) ) 

function getIds(obj) {
  for (var x in obj) {
    if (typeof obj[x] === 'object') {
      getIds(obj[x]);
    } else if (x === 'id') {
      console.log(obj.id);
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM