如何递归列出对象属性并将它们全部列在"一级深度"对象中?



我想做以下事情:从一个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'
}

我写了一个递归函数,除了下面两个我无法解决的问题外,它会工作得很好:

  1. 字符串被解析为字符数组而不是字符串
  2. 我不知道如何检测'叶子'属性(终止条件),因为每个属性似乎总是有一个'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' }

最新更新