Estoy trabajando con un objeto que contiene propiedades con valores que son cadena de tipo o número de tipo. Algunas propiedades son objetos anidados, y estos objetos anidados también contienen propiedades con valores que podrían ser tipo cadena o número de tipo. Tome el siguiente objeto como ejemplo simplificado:

var myObj = {
  myProp1: 'bed',
  myProp2: 10,
  myProp3: {
    myNestedProp1: 'desk',
    myNestedProp2: 20
  }
};

Quiero que todos estos valores sean de tipo cadena, por lo que cualquier valor que sea un número de tipo deberá convertirse.

¿Cuál es el enfoque más eficiente para lograr esto?

Intenté usar for..in y también jugué con Object.keys, pero no tuve éxito. Cualquier idea sería muy apreciada.

3
asw1984 27 oct. 2017 a las 23:10

5 respuestas

La mejor respuesta

Object.keys debería estar bien, solo necesita usar la recursión cuando encuentre objetos anidados. Para lanzar algo a cadena, simplemente puedes usar este truco

var str = '' + val;
var myObj = {
  myProp1: 'bed',
  myProp2: 10,
  myProp3: {
    myNestedProp1: 'desk',
    myNestedProp2: 20
  }
};

function toString(o) {
  Object.keys(o).forEach(k => {
    if (typeof o[k] === 'object') {
      return toString(o[k]);
    }
    
    o[k] = '' + o[k];
  });
  
  return o;
}

console.log(toString(myObj));
7
Martin Adámek 27 oct. 2017 a las 20:27

Puede usar un método recursive que revisa todos los keys.

El método Object.keys() devuelve una matriz de propiedades enumerables propias de un objeto dado.

Hay dos casos:

  • si el operador typeof devuelve object, entonces debe recuperar la función.

  • de lo contrario, solo necesita aplicar el método String().

Pero puede usar el operador ternary para la solución one-line.

 typeof myObj[key] == 'object' ? replace(myObj[key]) : myObj[key]= myObj[key].toString();
var myObj = {
  myProp1: 'bed',
  myProp2: 10,
  myProp3: {
    myNestedProp1: 'desk',
    myNestedProp2: 20
  }
};
function replace(myObj){
  Object.keys(myObj).forEach(function(key){
    typeof myObj[key] == 'object' ? replace(myObj[key]) : myObj[key]= String(myObj[key]);
  });
}
replace(myObj);
console.log(myObj);
2
Mihai Alexandru-Ionut 27 oct. 2017 a las 21:11

No es exactamente lo que se pidió, pero puede ser útil. Implementación con lodash

const person = {
  name: 'John',
  age: 25,
  address: {
    street: 'Green',
    houseNumber: 11
  },
  verified: true,
  bio: null,
  createdAt: NaN
};

function convertValuesToStringsDeep(obj) {
  return _.cloneDeepWith(obj, value => {
    return !_.isPlainObject(value) ? _.toString(value) : undefined;
  });
}

const copy = convertValuesToStringsDeep(person);
console.log(copy);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

La copia del objeto será:

{
  "name": "John",
  "age": "25",
  "address": {
    "street": "Green",
    "houseNumber": "11"
  },
  "verified": "true",
  "bio": "",
  "createdAt": "NaN"
 }
0
Johan Willfred 8 feb. 2020 a las 17:09

Use el método toString (); referencia de mozilla aquí

var myObj = {
  myProp1: 'bed',
  myProp2: (10).toString(),
  myProp3: {
    myNestedProp1: 'desk',
    myNestedProp2: (20).toString()
  }
};
-2
pellucidcoder 27 oct. 2017 a las 20:15

Puede usar la función lodash cloneDeepWith.

import * as _ from 'lodash';

var myObj = {
  myProp1: 'bed',
  myProp2: 10,
  myProp3: {
    myNestedProp1: 'desk',
    myNestedProp2: 20
  }
};

function toString(obj) {
    return _.cloneDeepWith(obj, val => val.toString());
}

console.log(toString(myObj));
0
Motin 25 sep. 2018 a las 13:32