我想做以下事情:从一个JS对象,我想构建第二个,从第一个递归列出所有属性,但都在'一级',其名称是第一个对象内的'路径'。
下面是一个例子。下面的对象…
{
level1_simple: 'foo',
level1_object: {
level2_a: 'bar',
level2_b: 'bar2'
},
level1_array: [
{
property1: 'foobar',
property2: 'foobar2'
},
'element2'
]
}
应翻译为:
{
level1_simple: 'foo',
level1_object[level2_a]: 'bar',
level1_object[level2_b]: 'bar2',
level1_array[0][property1]: 'foobar',
level1_array[0][property2]: 'foobar2',
level1_array[1]: 'element2'
}
我写了一个递归函数,除了下面两个我无法解决的问题外,它会工作得很好:
- 字符串被解析为字符数组而不是字符串
- 我不知道如何检测'叶子'属性(终止条件),因为每个属性似乎总是有一个'0'属性,它本身有一个'0'属性,等等。
function _treatDataRecursive( data, newData, prefix )
{
console.log( 'Entering: ' + prefix +"n" );
// Iterate over the properties of data
for( property in data )
{
console.log( 'Listing properties: ' + property + " value = " + data[property] + "n" );
// Build property symfonyzed name (using recursion)
var newPropName = prefix + '[' + property + ']';
// Check if property is a leaf
var type = typeof property;
if( type === 'string' || type === 'number' || type === 'boolean' )
{
console.log( 'Property is a leaf: ' + property +"n" );
// Property is a leaf: add property/value to newData
newData[newPropName] = data[property];
} else {
// Recursive call to go one level deeper
_treatDataRecursive( property, newData, newPropName );
}
}
}
你只有一个大问题。您应该使用property
的实际值,而不是property
本身。
function _treatDataRecursive(data, newData, prefix) {
for (var property in data) {
// if prefix is empty, don't decorate the property
var newPropName = prefix ? prefix + '[' + property + ']' : property;
// get the type of the actual value, not the `property`
var type = typeof data[property];
// If it is an object and not null do the recursion
if (type === 'object' && data[property] !== null) {
_treatDataRecursive(data[property], newData, newPropName);
} else {
// Most likely a leaf, don't recurse now
newData[newPropName] = data[property];
}
}
}
var obj = {};
_treatDataRecursive(data, obj, "");
console.log(obj);
{ level1_simple: 'foo',
'level1_object[level2_a]': 'bar',
'level1_object[level2_b]': 'bar2',
'level1_array[0][property1]': 'foobar',
'level1_array[0][property2]': 'foobar2',
'level1_array[1]': 'element2' }