查找关键字包含点,并用@
问题描述:
替换我有嵌套的对象,可以有任何深度的任意数量的键。 我想替换“。”在所有键(如果包含)中加上“@”我们如何以有效的方式做到这一点。查找关键字包含点,并用@
实施例节点的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"]["[email protected]@WaterfallStep"]=tempstate["state"]["BotBuilder.Data.WaterfallStep"]
tempstate["state"]["[email protected]@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["[email protected]@SessionState"]=finalobj
var secondrootobj={"[email protected]@SessionState":finalobj}
return secondrootobj;
}
答
这里是一个函数,它接受一个对象或数组,并且该对象的按键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
,此解决方案将超出堆栈。
+0
非常感谢你,工作像魅力一样 –
“任意深度处的任意数量的键” d4nyll
但任何数量的密钥都可以..在任何深度..键名也可以是任何..这个文件我从服务器..我不能在服务器端更改.. –