我有嵌套对象,可以在任何深度都有任意数量的键。 我想替换"。"在所有键(如果包含)中使用" @"我们如何以有效的方式做到这一点。
示例节点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;
}
答案 0 :(得分:1)
这是一个获取对象或数组的函数,以及该对象的键的target
和replacement
值。然后,它将返回一个新对象,其中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
,此解决方案将超出堆栈。