递归重命名对象键

And*_*Gee 8 javascript recursion jquery multidimensional-array

我有一个递归函数来重命名对象的键名,但我无法弄清楚如何重命名2个键(问题键是对象)

我认为问题在于我正在检查对象类型但是如何在该点重命名密钥?

实际的阵列非常大,但下面是一个减少的版本.

任何帮助赞赏.

var keys_short = ['ch','d','u','tz'];
var keys_long = ['children','data','user_id','time_zone'];
function refit_keys(o){
    build = {};
    for (var i in o){
        if(typeof(o[i])=="object"){
            o[i] = refit_keys(o[i]);
            build = o;
        }else{
            var ix = keys_short.indexOf(i);
            if(ix!=-1){
                build[keys_long[ix]] = o[keys_short[ix]];
            }
        }
    }
    return build;
}
Run Code Online (Sandbox Code Playgroud)

我的输入如下:

{
    "id":"1",
    "ch":[
        {
            "id":"3",
            "ch":[
            ],
            "d":{
                "u":"3",
                "tz":"8.00"
            }
        },
        {
            "id":"45",
            "ch":[
                {
                    "id":"70",
                    "ch":[
                        {
                            "id":"43",
                            "ch":[
                            ],
                            "d":{
                                "u":"43",
                                "tz":"-7.00"
                            }
                        }
                    ],
                    "d":{
                        "u":"70",
                        "tz":"-7.00"
                    }
                }
            ],
            "d":{
                "u":"45",
                "tz":"-7.00"
            }
        }
    ],
    "d":{
        "u":"1",
        "tz":"8.00"
    }
}
Run Code Online (Sandbox Code Playgroud)

我的输出是这样的:

{
    "id":"1",
    "ch":[
        {
            "id":"3",
            "ch":[
            ],
            "d":{
                "user_id":"3",
                "time_zone":"8.00"
            }
        },
        {
            "id":"45",
            "ch":[
                {
                    "id":"70",
                    "ch":[
                        {
                            "id":"43",
                            "ch":[
                            ],
                            "d":{
                                "user_id":"43",
                                "time_zone":"-7.00"
                            }
                        }
                    ],
                    "d":{
                        "user_id":"70",
                        "time_zone":"-7.00"
                    }
                }
            ],
            "d":{
                "user_id":"45",
                "time_zone":"-7.00"
            }
        }
    ],
    "d":{
        "user_id":"1",
        "time_zone":"8.00"
    }
}
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 9

那里有几个问题.

一个是由于未能在函数中声明您的变量,您将成为隐含全局恐怖的牺牲品build.

但逻辑也有问题,这里是一个最小的重做:

var keys_short = ['ch','d','u','tz'];
var keys_long = ['children','data','user_id','time_zone'];
function refit_keys(o){
    var build, key, destKey, ix, value;

    build = {};
    for (key in o) {
        // Get the destination key
        ix = keys_short.indexOf(key);
        destKey = ix === -1 ? key : keys_long[ix];

        // Get the value
        value = o[key];

        // If this is an object, recurse
        if (typeof value === "object") {
            value = refit_keys(value);
        }

        // Set it on the result using the destination key
        build[destKey] = value;
    }
    return build;
}
Run Code Online (Sandbox Code Playgroud)

实例 | 资源

但我建议使用键映射而不是并行数组:

var mapShortToLong = {
    "ch": "children",
    "d":  "data",
    "u":  "user_id",
    "tz": "time_zone"
};
function refit_keys(o){
    var build, key, destKey, ix, value;

    build = {};
    for (key in o) {
        // Get the destination key
        destKey = mapShortToLong[key] || key;

        // Get the value
        value = o[key];

        // If this is an object, recurse
        if (typeof value === "object") {
            value = refit_keys(value);
        }

        // Set it on the result using the destination key
        build[destKey] = value;
    }
    return build;
}
Run Code Online (Sandbox Code Playgroud)

实例 | 资源

  • @benoror:我不认为我声称它更好或更快,但并行阵列通常是一个维护问题.太容易修改一个而不是另一个.更难以错误地修改属性初始值设定项的*half*.;-) (3认同)
  • 超越。工作完美,教给我一些东西,找到了更好的方法 (2认同)

Bog*_*n D 5

有点晚了,但我正在寻找一个很好的简短实现,它也处理数组(前面的答案没有),所以我决定发布我的通用 ES6 实现,因为它可能对某些人有所帮助:

function deepMapKeys(originalObject, callback) {
  if (typeof originalObject !== 'object') {
    return originalObject
  }

  return Object.keys(originalObject || {}).reduce((newObject, key) => {
    const newKey = callback(key)
    const originalValue = originalObject[key]
    let newValue = originalValue
    if (Array.isArray(originalValue)) {
      newValue = originalValue.map(item => deepMapKeys(item, callback))
    } else if (typeof originalValue === 'object') {
      newValue = deepMapKeys(originalValue, callback)
    }
    return {
      ...newObject,
      [newKey]: newValue,
    }
  }, {})
}
Run Code Online (Sandbox Code Playgroud)

对于有问题的案例,调用将是:

deepMapKeys(inputObject, key => (keys_long[keys_short.indexOf(key)] || key))
Run Code Online (Sandbox Code Playgroud)

话虽如此,如果您可以使用 npm,那么有几个包(这里是一个另一个..)