【问题标题】:Accessing multiple property values of an object within an object without knowing the names在不知道名称的情况下访问对象内对象的多个属性值
【发布时间】:2016-07-07 13:24:40
【问题描述】:

对于

var data = { "title1": {"subtitle1": "one", "subtitle2": "two"}, "title2": "three", "title3": "four" };

我可以使用:

for (var key in data) {
  console.log(key);
}

获得:

title1

title2

title3

我可以使用:

var key = Object.keys(data)[0];

for (var prop in data[key]){
  console.log(data[key][prop]);
}

获得:

one 

two

问题:我可以用什么来获得:

one

two

three

four

【问题讨论】:

    标签: javascript object properties


    【解决方案1】:

    试试这个

    var data = {
      "title1": {
        "subtitle1": "one",
        "subtitle2": "two"
      },
      "title2": "three",
      "title3": "four"
    };
    var output = [];
    Object.keys(data).forEach(function(key) {
      if (typeof data[key] == "object") {
        Object.keys(data[key]).forEach(function(innerKey) {
          output.push(data[key][innerKey])
        });
      } else {
        output.push(data[key]);
      }
    });
    console.log(output);

    【讨论】:

    • 谢谢,这很好用。那么 forEach 函数只是作用于数组的每个元素?感谢所有回复的人
    • @fivedoor 是的,在这种情况下,数组的元素是关键。
    【解决方案2】:

    您可以使用迭代递归方法。

    function iter(object) {
        Object.keys(object).forEach(function (k) {
            if (typeof object[k] === 'object') {
                iter(object[k]);
                return;
            }
            console.log(object[k]);
        });
    }
    
    var data = { "title1": { "subtitle1": "one", "subtitle2": "two" }, "title2": "three", "title3": "four" };
    
    iter(data);

    【讨论】:

      【解决方案3】:

      您正在寻找的是一个递归循环。来自this SO page:

      function eachRecursive(obj)
      {
          for (var k in obj)
          {
              if (typeof obj[k] == "object" && obj[k] !== null)
                  eachRecursive(obj[k]);
              else
                  console.log(k, obj[k]);
          }
      }
      

      (第 8 行是你做事的地方,在这种情况下,我注销了键和值)

      【讨论】:

        【解决方案4】:

        你可以试试这个

        var data = { "title1": {"subtitle1": "one", "subtitle2": "two"}, "title2": "three", "title3": "four" };
        function getValues(obj) {
                var values=[]
            if (obj){
                Object.keys(obj).forEach(function (key) {
                        if (typeof obj[key] == "object"){
                     values.push(getValues(obj[key]));
                }else {
                    values.push(obj[key])
                }
                    });
            }
            return [].concat.apply([], values);
        }
        console.log(getValues(data))
        

        【讨论】:

          【解决方案5】:

          您可以使用递归函数深入挖掘对象层次结构并以所需的任何格式列出所有值。类似的东西

           function getValues(obj) {
             var returnVal = '';
             if (obj !== null) {
               if (typeof obj === 'object') {
                 Object.keys(obj).forEach(function(key) {
                   returnVal = returnVal + getValues(obj[key]) + '\n';
                 });
               } else {
                 returnVal = returnVal + obj + '\n';
               }
             }
             return returnVal;
           }
          
          
           var data = {
             "title1": {
               "subtitle1": "one",
               "subtitle2": "two"
             },
             "title2": "three",
             "title3": "four"
           };
          
           console.log(getValues(data));

          【讨论】:

            【解决方案6】:

            如果您想在数据结构上更通用,可以使用JSONPath 直接访问 json 叶:

            当在 Xpath 中所有叶表达式为 //*[not(*)],而在 JSONPath 中则变为 $..[?(@.length>=0)],这样你就有了

            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 data = { "title1": {"subtitle1": "one", "subtitle2": "two"}, "title2": "three", "title3": "four" };
            
            //
            // xpath all leaf expression is //*[not(*)]
            // in jspath becomes $..[?(@.length>=0)]
            var jsonObjectLeafValues = 
                jsonPathRead(data,"$..[?(@.length>=0)]");
            
            // this XPath will read all the id properties starting from the root element
            console.log( JSON.stringify( jsonObjectLeafValues, null, 2 ) )

            此 json 路径版本改编自原始版本,可在here 使用。

            【讨论】:

              猜你喜欢
              • 2013-05-10
              • 2018-11-28
              • 2016-07-02
              • 1970-01-01
              • 1970-01-01
              • 2011-07-04
              • 2023-03-31
              • 2021-01-27
              • 1970-01-01
              相关资源
              最近更新 更多