1

For

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

I can use:

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

To get:

title1

title2

title3

I can use:

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

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

To get:

one 

two

Question: What can I use to get:

one

two

three

four

6 Answers 6

2

try this

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

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, this works great. So the forEach function just acts on each element of the array? Thanks to everyone who responded
@fivedoor yes, and in this case element of the array is the key.
2

You coud use an iterative recursive approach for it.

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

Comments

0

What you're looking for is a recursive loop. From 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]);
    }
}

(line 8 is where you do your stuff, in this case I logged out the key and value)

Comments

0

you can try this

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

Comments

0

You could use a recursive function to dig deep down the object hierarchy and list out all the values in any format required. Something of this sort

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

Comments

0

If you want to be more generic on data structures you can use JSONPath to access json leafs directly:

When in Xpath all leaf expression is //*[not(*)], while in JSONPath this becomes $..[?(@.length>=0)], so that you have

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

This json path version was adapted from the original version and it is available here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.