I have an object which has inner objects and properties defined like this:
var obj = {obj1 : { "prop1" : "nothing", "prop2" : "prop"},
obj2 : {"prop1" : "nothing", "prop2" : "prop"},
pr1 : "message",
pr2 : "mess"
};
Normally to iterate every property of an object , the for .. in loop can do the trick
for (property in obj){
if (obj.hasOwnProperty(property)){
console.log(property + " " + obj[property]);
}
}
the console displayed :
obj1 [object Object]
obj12 [object Object]
pr1 message
pr2 mess
However how to iterate the inner objects (obj1, obj2) and their own properties (prop1,prop2) ?
Recursion is your friend:
function iterate(obj) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object")
iterate(obj[property]);
else
console.log(property + " " + obj[property]);
}
}
}
Note: don't forget to declare property locally using var!
That's great anwsers, although the array cases is not covered, here's my contribution:
var getProps = function (obj) {
for (var property in obj) {
if (obj.hasOwnProperty(property) && obj[property] != null) {
if (obj[property].constructor == Object) {
getProps(obj[property]);
} else if (obj[property].constructor == Array) {
for (var i = 0; i < obj[property].length; i++) {
getProps(obj[property][i]);
}
} else {
console.log(obj[property]);
}
}
}
}
getProps(myObject);
To simply display the object structure, I often use: console.log (JSON.stringify (obj))
You can use recursion to achieve that:
function Props(obj) {
function getProps(obj){
for (var property in obj) {
if (obj.hasOwnProperty(property)){
if (obj[property].constructor == Object) {
console.log('**Object -> '+property+': ');
getProps(obj[property]);
} else {
console.log(property + " " + obj[property]);
}
}
}
}
getProps(obj);
}
see http://jsfiddle.net/KooiInc/hg6dU/
Related
var key = " ";
var myBio = {
"name":"Sathya",
"age":"23",
"position":"Soft.Engineer",
"email":
{
"email1":"sathya#gmail.com",
"email2":"sathya#knstek.com"},
};
for (key in myBio){
var y = myBio[key];
console.log(key+" : "+ y);
}
output:
name : Sathya
age : 23
position : Soft.Engineer
email : [object Object]
Required Output:
name : Sathya
age : 23
position : Soft.Engineer
email :
email1:sathya#gmail.com
email2:sathya#knstek.com
I can print this Emails separately using another loop. But I want to print with main loop only . Any ways to do this using JavaScript??
You could use a recursive function to get this done.. example
function logRecursive(object){
for (key in object){
var value=object[key];
if(typeof value === 'object'){
console.log('{');
logRecursive(value)
console.log('}');
}else{
console.log(value);
}
}
function recursion(myBio) {
for (var key in myBio) {
if (typeof(myBio[key]) == 'object') {
recursion(myBio[key]);
} else {
alert("Key: " + key + " Values: " + myBio[key]);
}
}
}
use this subroutine if you have nested json
Try this:
var myBio = {
"name" : "Sathya",
"age" : "23",
"position" : "Soft.Engineer",
"email" : {
"email1" : "sathya#gmail.com",
"email2" : "sathya#knstek.com"
},
};
function print(bio) {
for (var key in bio) {
if (typeof(bio[key]) == 'object') {
print(bio[key]);
} else {
console.log(key + ": " + bio[key]);
}
}
}
print(myBio);
Most people searching in Google and finding this question are probably looking for something like this:
console.log(JSON.stringify(object, null, 2));
This prints deeply nested JSON to the console without the annoying "[Object]".
The last two parameters are optional. The 2 says to pretty print the JSON with an indent of 2. If left blank, will output non-formatted JSON.
This does not answer this specific question, but hopefully will answer those searching for "Print nested JSON Javascript".
Try this :
var myBio = {
"name":"Sathya",
"age":"23",
"position":"Soft.Engineer",
"email": {
"email1":"sathya#gmail.com",
"email2":"sathya#knstek.com"
}
};
var result = parseJSON(myBio);
console.log(result);
function parseJSON(obj) {
var parsedData = '';
for(var i in obj) {
if (typeof obj[i] == 'object') {
parsedData += parseJSON(obj[i]);
}else {
parsedData += i +' : '+ obj[i];
}//end if
parsedData += '\n';
}//end for
return parsedData;
}//end function
I have a json object which looks like this:
var testJ = {"ROOT":{
dir : 'app',
files : [
'index.html',
{
dir : 'php',
files: [
'a.php',
{
dir : 'extras',
files : [
'a.js',
'b.js'
]
}
]
}
]
}};
I need to extract all the files and append into an array (index.html,a.php,a.js..etc)
For this I wrote a javascript code as follows:
var arr=[];
function scan(obj,append)
{
var k;
if (obj instanceof Object) {
for (k in obj){
if (obj.hasOwnProperty(k)){
if(k=='files')
{
scan( obj[k],1 );
}
}
}
} else {
body += 'found value : ' + obj + '<br/>';
if(append == 1)
arr.push(obj);
alert("Arr"+ arr);
};
};
scan(testJ,0);
I am not able to figure out where am I going wrong. Could some give me pointers?
var res = [];
function gather(j) {
for (var k in j) {
if (k === 'files') {
addFiles(j[k]);
} else if (typeof j[k] === 'object') {
gather(j[k]);
}
}
}
function addFiles(f) {
for (var i = 0; i < f.length; i++) {
if (typeof f[i] === "string") {
body += 'found value : ' + obj + '<br/>';
res.push(f[i]);
} else {
gather(f[i]);
}
}
}
gather(testJ);
Free tips:
instanceof is some cancerous stuff. Why does instanceof return false for some literals?
Always, always use === for comparison, not ==
I also wouldn't blindly use hasOwnProperty unless you're afraid the thing you're operating on might have a modified prototype, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in just for simplicity.
How about a map reduce approach?:
function mapJ(subject) {
return subject.files.map(function(item) {
if (typeof item === "string") {
return item;
} else {
return parseJ(item);
}
});
}
function reduceJ(subject) {
return subject.reduce(function(prev, cur) {
return prev.concat(cur);
}, []);
}
function parseJ(subject) {
return reduceJ(mapJ(subject));
}
var result = parseJ(testJ));
I've got an object containing user-data alongside some dates. I'd like to format these dates (as they are delivered like this 2015-02-13T18:25:37+01:00).
I'd like to have the values of the object changed in-place but how can I do this?
I traverse the object like this:
$.each(myObject, formatDates)
var isDate = function(value) {
return (value!==null && !isNaN(new Date(value)))
}
var formatDates = function(key, value){
if (isDate(value)) {
// Change value here
console.log("key:" + key + " value: " + value)
}
// Recursive into child objects
if (value !== null && typeof value === "object") {
$.each(value, formatDates)
}
}
You can use this
function iterate(obj) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
iterate(obj[property]);
} else {
// do your date thing
}
}
}
return obj;
}
iterate(object)
I'm working with Json Object:
var someobj = {
'key':'value',
'key':'value',
'objectkey':{'key':'value','key':'value'}
}
While iterating, i want the result in console.log as:
KEY: key && VALUE: value
KEY: key && VALUE: value
OKEY: key && OKEYVALUE: value
While iterating I only get the first level, I can't seem to get it into the values that are the objects. I guess some sort of length could work:
EDIT2: Now with this inner loop it iterates and I get letters for external values, the inner values get logged completely.
var registration_form = {
'registration_form':{
'Display Name':'input',
'Username':{'inpute':'text','id':'some_id'},
'Password':'input',
'Email':'input',
'Captcha':'input'
}
};
function iterateNodes(data) {
for (var key in data){
var obj = data[key];
for(var prop in obj){
if(obj.hasOwnProperty(prop)){
var inobj = obj[prop];
for(var prop in inobj){
console.log(inobj[prop])
}
}else{
console.log(obj)
}
}
}
}
iterateNodes(registration_form);
In general you can iterate over properties of an object in this way:
for (var k in o) {
if (o.hasOwnProperty(k)) {
console.log('k: ' + k + ', v: ' + o[k])
}
}
so you can use recursion to go deeper than one level
function hasproperty(o) {
if (typeof o === 'object') {
for (var k in o) {
if (o.hasOwnProperty(k)) {
return true;
}
}
}
return false;
};
function iterate(o) {
for (var k in o) {
if (o.hasOwnProperty(k)) {
if (hasproperty(o[k])) {
console.log('within ' + k);
iterate(o[k]);
console.log('exit ' + k);
} else {
console.log('K: ' + k + ', V:' + o[k]);
}
}
}
};
Please try this out:
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
var someobj = {
'key1':'value1',
'key2':'value2',
'objectkey3':{'key01':'value01','key02':'value02'}
};
jQuery.each(someobj, function(i, val) {
if (typeof val == 'string'){
console.log("key : "+i+" value: "+val);
}else{
jQuery.each(val, function(j, val2) {
console.log("key : "+j+" value: "+val2);
});
}
});
</script>
If I do this:
for (var i in obj) {
if (obj.hasOwnProperty(i)) console.log("Has property: " + i);
else console.log("Doesn't have property: " + i);
}
Will obj.hasOwnProperty(i) ever return false? If so, when?
The idea of using hasOwnProperty within a loop is to resolve to false when looping over inherited properties. This avoids what Douglas Crockford refers to as a "deep-dredge."
Example from https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty :
var buz = {
fog: 'stack'
};
for (var name in buz) {
if (buz.hasOwnProperty(name)) {
alert("this is fog (" + name + ") for sure. Value: " + buz[name]);
}
else {
alert(name); // toString or something else
}
}
Example from https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty - doesn't show when hasOwnProperty can return false.
Here's a test case that does show that:
// From some library or earlier in your code
Object.prototype.xxx = "xxx";
// Your object
var data = { member: "member" };
for (var key in data) {
if( data.hasOwnProperty(key) ) {
alert(key); // alert("member")
}
else {
alert(key); // alert("xxx")
}
}