我有一个递归函数来重命名对象的键名,但是我无法弄清楚如何重命名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;
}
我的输入如下:
{
"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"
}
}
我的输出如下:
{
"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"
}
}
答案 0 :(得分:7)
那里有几个问题。
一个是因为你未能在函数中声明build
变量而成为The Horror of Implicit Globals的牺牲品。
但逻辑也存在问题,这里是最小的改造:
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;
}
但是我建议使用键映射而不是并行数组:
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;
}
答案 1 :(得分:2)
问题之一可能是变量build
实际上是一个全局变量。因此,它只包含递归中第一个深度的结果。
在var
之前添加build
应解决部分问题。
答案 2 :(得分:2)
有点晚了,但是我一直在寻找一个不错的简短实现,它也可以处理数组(前面的答案没有),所以我决定发布我的通用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,
}
}, {})
}
对于有问题的案例,电话为:
deepMapKeys(inputObject, key => (keys_long[keys_short.indexOf(key)] || key))
答案 3 :(得分:0)
我喜欢这种方法。但是我偶然发现了这一点:
您这样称呼它:deepMapKeys({testValue:["justString"]}, key => (key));
returnValue包含:
{0: "j", 1: "u", 2: "s", 3: "t", 4: "S", 5: "t", 6: "r", 7: "i", 8: "n", 9: "g"}
长度:1
会说,它将我的字符串转换为数组。