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)
那里有几个问题.
一个是由于未能在函数中声明您的变量,您将成为隐含全局恐怖的牺牲品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)
有点晚了,但我正在寻找一个很好的简短实现,它也处理数组(前面的答案没有),所以我决定发布我的通用 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,那么有几个包(这里是一个,另一个..)