6

I want to replace the whitespace of keys in a nested object. I have an object as follows:

     var data = 
 { 'General Information':
             { 'Referral No': '123123',
               Marketer: '',
               Casemanager: 'Alexis Clark',
               'CM Username': '',
               VOC: '',
               'Foreign Voluntary': '',
            },
     'Account Name': 'CTS Health',
    }

What i did is:

 for (var k in data) {
    if (k.replace(/\s/g, '') !== k) {
        data[k.replace(/\s/g, '')] = data[k];
        if (data[k] !== null && typeof data[k] === 'object') {
            for (var x in data[k]) {
                if (x.replace(/\s/g, '') !== x) {
                    data[k][x.replace(/\s/g, '')] = data[k][x];
                    delete data[k][x];
                }
            }
        }
        delete data[k];
    }
}

I get this:

{ GeneralInformation:
         { 'Referral No': '123123',
           Marketer: '',
           Casemanager: 'Alexis Clark',
           'CM Username': '',
           VOC: '',
           'Foreign Voluntary': '',
        },
    AccountName: 'CTS Health',
  }

What i want is:

{ GeneralInformation:
         { ReferralNo: '123123',
           Marketer: '',
           Casemanager: 'Alexis Clark',
           CMUsername: '',
           VOC: '',
           ForeignVoluntary: '',
        },
    AccountName: 'CTS Health',
  }

What am i doing wrong here??

3
  • 1
    Wow, that is some jacked up code. Nesting like that is very bad for readability. Avoid using delete Commented Apr 21, 2017 at 8:06
  • @dan, it doesn't even remove the whitespace of the very first key. Commented Apr 21, 2017 at 8:09
  • @AluanHaddad, Hmmm i really can't get it to work somehow. I know the solution must be really simple. But i am stucked :/ Commented Apr 21, 2017 at 8:10

4 Answers 4

5

You could use an iterative and recursive approach for nested objects.

function replaceKeys(object) {
    Object.keys(object).forEach(function (key) {
        var newKey = key.replace(/\s+/g, '');
        if (object[key] && typeof object[key] === 'object') {
            replaceKeys(object[key]);
        }
        if (key !== newKey) {
            object[newKey] = object[key];
            delete object[key];
        }
    });
}


var data = { 'General Information': { 'Referral No': '123123', Marketer: '', Casemanager: 'Alexis Clark', 'CM Username': '', VOC: '', 'Foreign Voluntary': '', }, 'Account Name': 'CTS Health' };

replaceKeys(data);
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

2 Comments

Nice, beat me to it
Nina, got it. Thanks for your answer.
0

Try recursive approach.

var replaceSpace = function (obj) {
  Object.keys(obj).forEach(function(key){
    var newKey = key.split(' ').join('');
    if(object[key] && typeof obj[key] === "object"){
      obj[newKey] = replaceSpace(obj[key])
    }else{
      obj[newKey] = obj[key]
    }

    if(key != newKey)
      delete obj[key]
  })
  return obj
}

4 Comments

This will fail if obj[key] === null
a= {};a[null] = 12;typeof a[null]; gives "number" when does it fails ??
typeof null === "object" note the other answers handle this
Right on. JavaScript has lots of pitfalls like that. I never use null in my own code, only undefined. I don't have to worry about this hazard and who needs two nulls. Interestingly, typeof null === "object" was a bug in BE's initial JavaScript engine in 1995. Language got standardized before he could fix it.... go figure
0

We can create a new object instead of mutating the existing one. This both makes it easier to test and also reduces potential for bugs cropping up due to sharing.

function withNormalizedKeys(o) {
  return Object.entries(o)
    .map(([key, value]) => [key.replace(/\s+/g, ''), value])
    .reduce((result, [normalizedKey, value]) => {
      result[normalizedKey] =
      value && typeof value === 'object'
      ? withNormalizedKeys(value)
      : value;
    return result;
  }, {});
}

const data = {
  'General Information': {
    'Referral No': '123123',
    Marketer: '',
    Casemanager: 'Alexis Clark',
    'CM Username': '',
    VOC: '',
    'Foreign Voluntary': ''
  },
  'Account Name': 'CTS Health'
};
const normalized = withNormalizedKeys(data);
console.log(normalized);

5 Comments

It is also good practice for newcomers to learn to use block scoped variables. Also, how is immutable by default not simple?
@BekimBacaj I bet you write for (var i = 0....) { and if you do, it is proof that you are wrong. var, let and const are very different things. And the latter are preferable to the former.
-1: because you still have the double quotes surrounding the field names - which is what Sunil said he does not want. Also, why is it easier to test if you create a new object (versus updating an existing one)?
@Matt excuse me, but where are double quotes mentioned in the OP? This produces the same output as the accepted answer.
@AluanHaddad - run your code snippet and check the log output.
0

This works great for me

const replaceKeys = (object) => {
    Object.keys(object).forEach(function (key) {
        // const twoLower = key.toLowerCase();
        const removeSpace = key.replace(/\s+/g, '');
        const newKey = removeSpace.toString().toLowerCase();
        if (object[key] && typeof object[key] === 'object') {
            replaceKeys(object[key]);
        }
        if (key !== newKey) {
            object[newKey] = object[key];
            delete object[key];
        }
    });
    return object;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.