I have a json object which is variable (with possibly infinite sub-structures):
var myObject={
s1:{
s2:'2',
s3:'3'
},
s4:'4',
s5:{
s6:undefined
},
s7:'7'
};
I would like to find the first undefined member and to return it's reference, to be able to modify it anytime (by event triggered functions)
function findFirstUndefined(obj){
for (var key in obj){
if (typeof(obj[key]) === 'object'){
var recursion=findFirstUndefined(obj[key])
if (recursion!==false){
return recursion;
}
}
else if (obj[key]===undefined){
return obj[key];
}
}
return false;
}
But it doesn't return the reference of the member, but it's value:
var subObj=findFirstUndefined(myObject);
subObj="my updated cool var!!";
doesn't modify the object.
I found that a library like JsonPath could do the trick, but it seems to me kind of heavy for such a simple task.
Wouldn't it exists an elegant way to do so? Thank's!
I have a json object which is variable (with possibly infinite sub-structures):
var myObject={
s1:{
s2:'2',
s3:'3'
},
s4:'4',
s5:{
s6:undefined
},
s7:'7'
};
I would like to find the first undefined member and to return it's reference, to be able to modify it anytime (by event triggered functions)
function findFirstUndefined(obj){
for (var key in obj){
if (typeof(obj[key]) === 'object'){
var recursion=findFirstUndefined(obj[key])
if (recursion!==false){
return recursion;
}
}
else if (obj[key]===undefined){
return obj[key];
}
}
return false;
}
But it doesn't return the reference of the member, but it's value:
var subObj=findFirstUndefined(myObject);
subObj="my updated cool var!!";
doesn't modify the object.
I found that a library like JsonPath could do the trick, but it seems to me kind of heavy for such a simple task.
Wouldn't it exists an elegant way to do so? Thank's!
Share Improve this question asked Nov 21, 2012 at 23:20 SamiSami 7239 silver badges25 bronze badges 10- 2 You've got an object, not JSON. – Šime Vidas Commented Nov 21, 2012 at 23:23
-
You could return a string
"s1"
and access it usingmyObject[string]
. Not exactly pass by reference, but it's the best I can think of. – Vala Commented Nov 21, 2012 at 23:24 -
It looks like you return the undefined value:
else if (obj[key]===undefined){ return obj[key];
– gdoron Commented Nov 21, 2012 at 23:24 -
In order to change the value of an object property, you need to assign to a property reference, e.g.
obj.prop = 'new value';
. – Šime Vidas Commented Nov 21, 2012 at 23:27 - @ŠimeVidas you are right, I didn't double quoted everything, what I meant by json object is that i get it via a String and it doesn't contain any function – Sami Commented Nov 22, 2012 at 13:10
5 Answers
Reset to default 6JS doesn't do that. You could instead return a function that will assign to the missing entry?
return function(v) { obj[key] = v; };
In JS you cannot control manually if the value is passed, or the reference.
And only objects are passed by reference.
So unfortunately you just cannot do that.
As you requested it in ments I'll post a way of getting/setting these objects based on a string path. It's up to you whether you think it's too plicated of course, but here it is.
function getValue(object, path) {
value = object[path[0]];
if (path.length > 1) {
return getValue(value, path.slice(1, path.length))
}
return value;
}
function setValue(object, path, value) {
if (path.length > 1) {
setValue(object[path[0]], path.slice(1, path.length), value);
}
else {
object[path[0]] = value
}
}
You then use them like this: getValue(myObject, ["s1", "s2"]);
/ setValue(myObject, ["s1", "s2"], value);
. I haven't had a chance to test the code, but the approach should hold.
If you return obj[key]
you are returning a value obviously but try to return an array of two values [obj, key]
and you have a way of referencing that node. Or from your recursive function you can build up a multidimensional array with these kinds of pairs for later use.
function findFirstUndefinedPath(obj){
for (var key in obj){
var path=[key];
if (typeof(obj[key]) === 'object'){
var subPath=findFirstUndefinedPath(obj[key]);
if (subPath!==false){
return path.concat(subPath);
}
}
else if (obj[key]===undefined){
return path;
}
}
return false;
}