JSON.stringify无法转换数组

3

我知道我处理递归的方式可能不正确,但是很诚实地说,这可能是因为我在处理递归时出了错。以下是链接到示例

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

这里是原始的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
        }
    }
}]

JSON会像你预期的那样发送给函数。
propertyTest(oarsObject);

这里是证据证明它何时偏离正轨,以下是控制台的一部分代码 -
["latitude",0.5050715845821404]
["longitude",-1.604064725846865]
["height",0]
undefined
["positionReferenceType","geogWgs84"]
["latitude",0.5050926519562077]
["longitude",-1.5961047836759397]
["height",0]
undefined

请注意,前两个项最初会出现在日志中,然后只有positionReferenceType。还要注意未定义的JSON字符串。我确定这是因为我的递归有误。
在阅读了几篇文章之后,我知道JavaScript数组想要数字键,但我很好奇。 JSON.stringify()似乎在其中一些数组上起作用,而在其他数组上却不起作用。此外,结果是不一致的,在第一轮之后,positionReferenceType确实被字符串化了,尽管顺序显然是错误的(再次强调,我确定这是因为我的递归努力有问题)。
这样做的用例有两种。首先,我们想剥离原始JSON的不必要的“value”键,该JSON是由系统的某个部分生成的,我们无法在此时修改它。其次,系统的其他部分会使用我们希望从此类函数输出的离散较小的JSON位。输出应该是小的,单独的JSON字符串(类似于HTML输出中显示的内容)。输出应该是一个单一的JSON字符串,由下面示例中所示的单个键/值对组成。
[
    {
        "coordinateReferenceSystem": "26782,15851"
    },
    {
        "positionReferenceType": "geogWgs84"
    },
    {
        "latitude": 0.5050715845821404
    },
    {
        "longitude": -1.604064725846865
    },
    {
        "height": 0
    }
]

我甚至还没有接近组装整个JSON字符串的点,因为我仅仅是在努力正确地提取键值对。
我相信我在这里忽视了某些东西。我应该创建一个对象而不是数组来使一切都能够被串联吗?或者除了我提到的明显问题之外,是我的递归中的某些东西让我无法前进?

你正在声明数组,以便它仅在else子句中初始化。每当你找到一个对象并决定递归时,“arrayJSON”将是未定义的。 - Pointy
1
还要注意的是,因为每次将内容放入数组时都会对其进行重新初始化,所以最终你只会得到一个条目(最多)。 - Pointy
2
你应该在问题中说明你试图实现的最终结果 - Anentropic
我的意思是,输出应该是什么样子的呢... 你想要将令人烦恼的值结构扁平化为 {"geogWgs84": {"longitude": -1.5960947041991222}} 还是目前似乎你希望一切都以键值对数组的形式表示,如 ["geogWgs84", ["longitude", -1.5960947041991222]] - Anentropic
1
我不知道,因为你想要实现什么目标还不清楚。 - Pointy
显示剩余11条评论
2个回答

2
通常来说,有两种方法可以进行递归并获得单一的扁平化数组作为结果。
第一种是将结果数组作为参数传递,并且每次递归都会向其添加元素。
第二种是每次调用都返回一个数组,上层将其加入自己的结果中。
无论哪种方法,你都需要先测试是否为数组主题,然后再检查对象主题,因为数组是对象,通常你会想针对它们执行不同的操作。
此外,通常你将在递归之外处理结果(例如转换为JSON,然后记录),以保持递归简短和简单。
以下是使用第一种方法实现的示例,在顶层包括JSON转换。我已经尽可能重用了你的变量名。

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


1
你可能希望像Sheepy建议的那样,在递归函数外部限定结果数组的范围。
当它是一个数组值时,使用forEach,当它是一组对象时,使用for。这样你只处理了一个对象的推送,而不需要维护数组。 示例 jsFiddle
var arrayJSON = [];

function propertyTest(currentObject, key) {

    if (Array.isArray(currentObject)) {
        currentObject.forEach(propertyTest);
    } else {
        for (var returnKey in currentObject) {

            if (typeof currentObject[returnKey] === 'object') {
                propertyTest(currentObject[returnKey], returnKey);
            } else {
                var newKey = (returnKey === 'value' && key) ? key : returnKey;
                var newObj = {};
                newObj[newKey] = currentObject[returnKey];
                arrayJSON.push(newObj);

                $('#method1').append( newKey + ' -- ' + currentObject[returnKey] + '<br />');
            }
        }
    }
}

propertyTest(oarsObject);
console.log(JSON.stringify(arrayJSON););

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接