There are a couple of problems there.
One is that you're falling prey to The Horror of Implicit Globals by failing to declare your build
variable in the function.
But the logic has issues as well, here's a minimal reworking:
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;
// Only handle non-null objects
if (o === null || typeof o !== "object") {
return o;
}
// Handle array just by handling their contents
if (Array.isArray(o)) {
return o.map(refit_keys);
}
// We have a non-array object
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;
}
Live Example:
"use strict";
var input = {
"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"
}
};
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;
// Only handle non-null objects
if (o === null || typeof o !== "object") {
return o;
}
// Handle array just by handling their contents
if (Array.isArray(o)) {
return o.map(refit_keys);
}
// We have a non-array object
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;
}
console.log(refit_keys(input));
.as-console-wrapper {
max-height: 100% !important;
}
But rather than parallel arrays, I'd suggest using a mapping, via an object or a Map
:
// Object with no prototype to avoid false matches on `toString` and other built-ins
var mapShortToLong = Object.assign(Object.create(null), {
"ch": "children",
"d": "data",
"u": "user_id",
"tz": "time_zone"
});
function refit_keys(o){
var build, key, destKey, value;
// Only handle non-null objects
if (o === null || typeof o !== "object") {
return o;
}
// Handle array just by handling their contents
if (Array.isArray(o)) {
return o.map(refit_keys);
}
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;
}
Live Example:
"use strict";
var input = {
"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"
}
};
// Object with no prototype to avoid false matches on `toString` and other built-ins
var mapShortToLong = Object.assign(Object.create(null), {
"ch": "children",
"d": "data",
"u": "user_id",
"tz": "time_zone"
});
function refit_keys(o){
var build, key, destKey, value;
// Only handle non-null objects
if (o === null || typeof o !== "object") {
return o;
}
// Handle array just by handling their contents
if (Array.isArray(o)) {
return o.map(refit_keys);
}
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;
}
console.log(refit_keys(input));
.as-console-wrapper {
max-height: 100% !important;
}
Or in modern JavaScript:
// Using a `Map` here to provide a `Map` example, but you can ue an object as
// in the previous ones if you prefer if the keys are strings
const mapShortToLong = new Map([
["ch", "children"],
["d", "data"],
["u", "user_id"],
["tz", "time_zone"],
]);
function refit_keys(o){
// Only handle non-null objects
if (o === null || typeof o !== "object") {
return o;
}
// Handle array just by handling their contents
if (Array.isArray(o)) {
return o.map(refit_keys);
}
const build = {};
for (const key in o) {
// Get the destination key
const destKey = mapShortToLong.get(key) || key;
// Get the value
let 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;
}
Live Example:
"use strict";
var input = {
"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"
}
};
// Using a `Map` here to provide a `Map` example, but you can ue an object as
// in the previous ones if you prefer if the keys are strings
const mapShortToLong = new Map([
["ch", "children"],
["d", "data"],
["u", "user_id"],
["tz", "time_zone"],
]);
function refit_keys(o){
// Only handle non-null objects
if (o === null || typeof o !== "object") {
return o;
}
// Handle array just by handling their contents
if (Array.isArray(o)) {
return o.map(refit_keys);
}
const build = {};
for (const key in o) {
// Get the destination key
const destKey = mapShortToLong.get(key) || key;
// Get the value
let 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;
}
console.log(refit_keys(input));
.as-console-wrapper {
max-height: 100% !important;
}