我有嵌套的对象,它可以在任何深度具有任意数量的键。
我要替换“。”在所有带有“ @”的键(如果包含)中,我们如何高效地做到这一点。

示例Node js对象

obj:{
        "BotBuilder.Data.SessionState": {
            "lastAccess": 1492886892545,
            "version": 14,
            "callstack": [
                {
                    "id": "*:/",
                    "state": {
                        "BotBuilder.Data.WaterfallStep": 0,
                        "BotBuilder.Data.Intent": "welcomeDialog"
                    }
                }
            ]
        }


目前,我正在使用硬编码解决方案,但任何键都可以在包含“。”的任何级别的对象中使用。我想概括解决这个问题的方法

我的代码:

replaceDot:function(doc){
    var finalobj={}
    var finaldata={}
    var finalcallstack=new Array();
    console.log("doc==>",doc)
    var callstack=doc["data"]["BotBuilder.Data.SessionState"]["callstack"]
    for(var i = 0; i < callstack.length; i++) {
        var tempcallstack={}
        if("BotBuilder.Data.WaterfallStep" in callstack[i]["state"]){
            tempcallstack["id"]=callstack[i]["id"]
            var tempstate={}
            tempstate["state"]=callstack[i]["state"]
            tempstate["state"]["BotBuilder@Data@WaterfallStep"]=tempstate["state"]["BotBuilder.Data.WaterfallStep"]
            tempstate["state"]["BotBuilder@Data@Intent"]=tempstate["state"]["BotBuilder.Data.Intent"]
            delete tempstate["state"]["BotBuilder.Data.WaterfallStep"]
            delete tempstate["state"]["BotBuilder.Data.Intent"]
            tempcallstack["state"]=tempstate["state"];
            finalcallstack.push(tempcallstack);
        }
        else{
            finalcallstack.push(callstack[i]);
        }
    }
    var obj={}
    finalobj["lastAccess"]=doc["data"]["BotBuilder.Data.SessionState"]["lastAccess"]
    finalobj["version"]=doc["data"]["BotBuilder.Data.SessionState"]["version"]
    finalobj["callstack"]=finalcallstack;
    obj["BotBuilder@Data@SessionState"]=finalobj
    var secondrootobj={"BotBuilder@Data@SessionState":finalobj}
    return secondrootobj;
}

最佳答案

这是一个接受对象或数组的函数,该对象的键的targetreplacement值。然后,它将返回一个新对象,其中在结果对象的键中将target的实例替换为replacement(使用String.prototype.replace)。



var substituteKeyDeep = function(obj, target, replacement) {
    // Get the type of the object. Array for arrays, Object for objects, null for anything else.
    try {
        var type = obj.constructor === Array ? Array
          : (obj.constructor === Object ? Object : null);
    } catch (err) {
        // A try/catch is actually necessary here. This is because trying to access the `constructor` property
        // of some values throws an error. For example `null.constructor` throws a TypeError.
        var type = null;
    }

    if (type === Array) {
        // Simply do a recursive call on all values in array
        var ret = [];
        for (var i = 0, len = obj.length; i < len; i++) {
            ret[i] = substituteKeyDeep(obj[i], target, replacement);
        }
    } else if (type === Object) {
        // Do a recursive call on all values in object, AND substitute key values using `String.prototype.replace`
        var ret = {};
        for (var k in obj) {
            ret[k.replace(target, replacement)] = substituteKeyDeep(obj[k], target, replacement);
        }
    } else {
        // For values that aren't objects or arrays, simply return the value
        var ret = obj;
    }

    return ret;
};

var data = {
    "BotBuilder.Data.SessionState": {
        "lastAccess": 1492886892545,
        "version": 14,
        "callstack": [
            {
                "id": "*:/",
                "state": {
                    "BotBuilder.Data.WaterfallStep": 0,
                    "BotBuilder.Data.Intent": "welcomeDialog"
                }
            }
        ]
    }
};

var dataWithRenamedKeys = substituteKeyDeep(data, /\./g, '@');

console.log(dataWithRenamedKeys);





请注意,在示例中,替换值(/\./g)是正则表达式,而不是字符串。这是因为需要使用带有全局修饰符(g)的正则表达式来替换对象键中所有出现的实例,而不仅仅是第一个实例。

编辑:快速免责声明!如果使用具有循环引用的对象调用substituteKeyDeep,则此解决方案将超出堆栈。

关于javascript - 查找键包含点并替换为@,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43564840/

10-09 23:55
查看更多