如何递归列出对象属性并将它们全部列在 'one-level-deep'-object 中?
How to recursively list object properties and list them all in a 'one-level-deep'-object?
我想做以下事情:我想从一个 JS 对象构建第二个对象,递归列出第一个对象的所有属性,但都在 'level one' 并且其名称是 'path' 在第一个对象中。
这是一个例子。以下对象...
{
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'
}
我写了一个递归函数,除了以下两个我无法解决的问题外,它运行良好:
- 字符串被解析为字符数组而不是字符串
- 我不知道如何检测 'leaf' 属性(终止条件),因为每个 属性 似乎总是有一个 '0' 属性,它本身有一个'0'属性,等等
这是完整的代码(由于上面的第 2 点导致无限循环):
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' }
我想做以下事情:我想从一个 JS 对象构建第二个对象,递归列出第一个对象的所有属性,但都在 'level one' 并且其名称是 'path' 在第一个对象中。
这是一个例子。以下对象...
{
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'
}
我写了一个递归函数,除了以下两个我无法解决的问题外,它运行良好:
- 字符串被解析为字符数组而不是字符串
- 我不知道如何检测 'leaf' 属性(终止条件),因为每个 属性 似乎总是有一个 '0' 属性,它本身有一个'0'属性,等等
这是完整的代码(由于上面的第 2 点导致无限循环):
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' }