在不知道名称的情况下访问对象内对象的多个属性值

时间:2016-07-07 13:24:40

标签: javascript object properties

对于

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

6 个答案:

答案 0 :(得分: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);

答案 1 :(得分:2)

试试这个

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);

答案 2 :(得分:0)

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

$("form#validate :input").on("change paste keyup", function () {
    $(this).toggleClass('notoke', !new RegExp($(this).data('regex')).test($(this).val()));
});

(第8行是你做的东西,在这种情况下我记录了键和值)

答案 3 :(得分:0)

你可以试试这个

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))

答案 4 :(得分:0)

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

 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));

答案 5 :(得分:0)

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

在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