I know that I have gone about this the wrong way and very honestly it could be because I am handling the recursion incorrectly, but if so I am unsure where I have gone wrong. Here is the link to the example.
Here is the JavaScript -
function propertyTest(currentObject, key) {
for (var property in currentObject) {
if (typeof currentObject[property] === "object") {
propertyTest(currentObject[property], property);
} else {
// this is only to test the output
$('#method1').append((property == 'value' && key ? key : property) + ' -- ' + currentObject[property] + '<br />');
propertyKey = (property == 'value' && key ? key : property);
propertyValue = currentObject[property];
var arrayJSON = [];
arrayJSON.push(propertyKey);
arrayJSON.push(propertyValue);
}
}
var JSONString = JSON.stringify(arrayJSON);
console.log(JSONString);
return JSONString;
}
Here is the original JSON -
var oarsObject = [{
"coordinateReferenceSystem": "26782,15851",
"positionReferenceType": "geogWgs84",
"geogWgs84": {
"latitude": {
"value": 0.50507158458214041
},
"longitude": {
"value": -1.604064725846865
},
"height": {
"value": 0.0
}
}
}, {
"coordinateReferenceSystem": "26782,15851",
"positionReferenceType": "geogWgs84",
"geogWgs84": {
"latitude": {
"value": 0.50509265195620767
},
"longitude": {
"value": -1.5961047836759397
},
"height": {
"value": 0.0
}
}
}, {
"coordinateReferenceSystem": "26782,15851",
"positionReferenceType": "geogWgs84",
"geogWgs84": {
"latitude": {
"value": 0.4963464715653228
},
"longitude": {
"value": -1.5960947041991222
},
"height": {
"value": 0.0
}
}
}, {
"coordinateReferenceSystem": "26782,15851",
"positionReferenceType": "geogWgs84",
"geogWgs84": {
"latitude": {
"value": 0.49632551101280209
},
"longitude": {
"value": -1.604015267530267
},
"height": {
"value": 0.0
}
}
}]
The JSON is sent to the function as you would expect -
propertyTest(oarsObject);
Here is the evidence of where it goes off of the rails, a snippet from the console -
["latitude",0.5050715845821404]
["longitude",-1.604064725846865]
["height",0]
undefined
["positionReferenceType","geogWgs84"]
["latitude",0.5050926519562077]
["longitude",-1.5961047836759397]
["height",0]
undefined
Notice how the first two items do appear in the log initially and then only positionReferenceType
thereafter. Also note the undefined JSON string. I'm sure this is because my recursion is wrong.
I'm aware that JavaScript arrays want numerical keys after reading several other posts but I am curious. JSON.stringify()
seems to work on some of these and not the others. Furthermore the results are inconsistent, after the first round positionReferenceType
does get stringified, albeit in what is apparently the wrong order (again, I am sure this is because my recursion effort is off).
The use case for this is two-fold. First we want to strip the unnecessary 'value' key of the original JSON that is being generated by a part of the system that we cannot modify at this point. Second, other parts of the system consumes the discrete smaller JSON bits we would hope to output from a function like this. Output should be small, individual JSON strings (similar to what is being shown in the HTML output). The output should be a single JSON string, made up of individual key / value pairs as shown in the example below.
[
{
"coordinateReferenceSystem": "26782,15851"
},
{
"positionReferenceType": "geogWgs84"
},
{
"latitude": 0.5050715845821404
},
{
"longitude": -1.604064725846865
},
{
"height": 0
}
]
I haven't even come close to the point of assembling the whole JSON string as I am stuck just trying to get the pairs out correctly.
I'm sure that I am overlooking something here. Should I create an object, instead of an array to get everything to stringify? Or is it something in my recursion tripping me up other than what I think are the obvious problems I've mentioned?
There are, generally, two ways to recur and get a single, flattened array as result.
Either way, you need to test for Array subject first, and check for Object subject later, because Array is Object, and usually you will want to do different things for them.
Also, normally you will process the result (e.g. convert to JSON and then log) outside the recursion, to keep the recursion short and simple.
Here is an implementation using the first method, that includes JSON conversion at top level. I have reused your variable name whenever possible.
function propertyTest( currentObject, array, key ) {
var result = array || [], o;
if ( Array.isArray( currentObject ) ) {
currentObject.forEach( function ( e ) { propertyTest( e, result ); } );
} else if ( typeof ( currentObject ) === 'object' ) {
if ( 'value' in currentObject && Object.keys( currentObject ).length === 1 ) {
propertyTest( currentObject.value, result, key );
} else {
for ( var property in currentObject ) {
propertyTest( currentObject[ property ], result, property );
}
}
} else {
result.push( o = {} );
o[ key ] = currentObject;
}
return array === undefined ? JSON.stringify( result ) : result;
}
var oarsObject = [{
"coordinateReferenceSystem": "26782,15851",
"positionReferenceType": "geogWgs84",
"geogWgs84": {
"latitude": {
"value": 0.50507158458214041
},
"longitude": {
"value": -1.604064725846865
},
"height": {
"value": 0.0
}
}
}, {
"coordinateReferenceSystem": "26782,15851",
"positionReferenceType": "geogWgs84",
"geogWgs84": {
"latitude": {
"value": 0.50509265195620767
},
"longitude": {
"value": -1.5961047836759397
},
"height": {
"value": 0.0
}
}
}, {
"coordinateReferenceSystem": "26782,15851",
"positionReferenceType": "geogWgs84",
"geogWgs84": {
"latitude": {
"value": 0.4963464715653228
},
"longitude": {
"value": -1.5960947041991222
},
"height": {
"value": 0.0
}
}
}, {
"coordinateReferenceSystem": "26782,15851",
"positionReferenceType": "geogWgs84",
"geogWgs84": {
"latitude": {
"value": 0.49632551101280209
},
"longitude": {
"value": -1.604015267530267
},
"height": {
"value": 0.0
}
}
}];
alert( propertyTest( oarsObject ) );