Davide
Davide

Reputation: 475

Iterate property object

I want to iterate object and covert the number to string but I don't know name of properties and how much are nested for example:

var a = {
    a: 1,
    b: {
       a: 2
    }
}

The result should be:

var a = {
    a: "1",
    b: {
       a: "2"
    }
}

I think I need a recursive function

Upvotes: 1

Views: 51

Answers (4)

Ben Aston
Ben Aston

Reputation: 55729

Something like this (requires an engine supporting default arguments).

function walk(o, action, index = 0, keys = Object.keys(o)) { 
  var item;

  if (index > keys.length) {
    return null; // End of siblings.
  }

  item = o[keys[index]];      

  if(item !== null && typeof item === 'object') { // null is an object.
    walk(item, action); // Children.
  } else {
    o[keys[index]] = action(item);
  }

  return walk(o, action, ++index); // Siblings.
}

var o = { foo: 1, bar: { bam: 2 } };
walk(o, p => (typeof p === 'number') && p.toString());

document.write('o.foo is now a ', typeof o.foo); // 'string'
document.write('<br/>');
document.write('o.bar.bam is now a ', typeof o.bar.bam); // 'string'

Upvotes: 0

Bogomil Dimitrov
Bogomil Dimitrov

Reputation: 139

You can write a simple recursive function that does the following:

  1. Checks if the current property is an Object or not.
  2. If so -> recursively calls the same function to cycle through the nested object's properties.
  3. If the current property is not an object -> checks if the value can be parsed to a number or not.
  4. Saves the original value if NaN occurs otherwise saves the parsed number.

    function convertToNumber(obj) {
    for(var prop in obj) {
        if(obj[prop] instanceof Object) {
            //If the current property is an object
            //calls itself recursively over it's props
            convertToNumber(obj[prop]);
        } else {
            //Like Try-Parse, it will return NaN if item
            //cannot be converted to number
            var temp = Number(obj[prop]);
            //Checks if the temporary variable is a valid number or NaN
            //If it's value is NaN it keeps the original value
            obj[prop] = !isNaN(temp) ?  temp : obj[prop] ;
        }
    }
    }
    

Upvotes: 0

thefourtheye
thefourtheye

Reputation: 239443

I prefer avoiding side-effects as much as possible. So, recursively create new objects and finally return the newly created object, like this

function rec(obj) {
  if (typeof obj === 'object') {
    var result = {};

    // iterate all the keys of the object
    for (key in obj) {

      // if the key is only defined on this object, not inherited
      if (obj.hasOwnProperty(key)) {

        // then recursively reconstruct the objects
        result[key] = rec(obj[key]);
      }
    }
    return result;
  }

  // if it is not an object, then stringify it and return.
  return '' + obj;
}

console.log(rec(a));
// { a: '1', b: { a: '2' } }

Upvotes: 1

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34189

You can implement a recursive function which will iterate through all own properties of the object and:

  • Convert every number property to a string
  • Run itself recursively for every object property

var a = {
    a: 1,
    b: {
       a: 2
    }
};

function convert(o)
{
  for (var k in o)
  {
    if (!o.hasOwnProperty(k)) continue; 

    switch (typeof o[k])
    {
      case 'number':
        o[k] = o[k].toString();
        break;
      case 'object':
        convert(o[k]); 
        break;
    }
  }
}

convert(a);

document.querySelector('pre').innerText = JSON.stringify(a, null, 4);
<pre></pre>

Upvotes: 1

Related Questions