el siguiente código es un objeto de la base de datos
{ "id_": "1", "name": "Enemy x", "image": "image.png", "stats": { "level": 1, "attack": 5, "defense": 0 } }Y necesita editar ataque o defensa, pero con un "puntero" guardado en una constante, todo esto de forma dinámica ya que el valor a editar podría estar en un tercer o cuarto nivel del objeto. por ejemplo:
const edit = 'stats/attack'; // const edit = 'stats/other/example'; <- exampleTengo algunas ideas, pero no sé si existen mejores prácticas para esto, o cómo buscarlo en Internet, ya que no puedo encontrar nada parecido.
usar una reducción:
const data = { id_ : '1' , name : 'Enemy x' , image : 'image.png' , stats: { level : 1 , attack : 5 , defense : 0 } } function getVal( obj, key ) { return key.split('/').reduce((o,v)=>o[v],obj) } console.log('--> ', getVal( data, 'stats/attack' ))En caso de un camino equivocado:
const data = { id_ : '1' , name : 'Enemy x' , image : 'image.png' , stats: { level : 1 , attack : 5 , defense : 0 } } const getVal = ( obj, path ) => path.split('/').reduce((o,v)=> o?.[v] ,obj) // better than `o[v] ?? 'error!`' console.log('1-->', getVal( data, 'stats/attack' )) // --> 5 console.log('2-->', getVal( data, 'stats/xxx' )) // --> undefined console.log('3-->', getVal( data, 'zzz/xxx' )) // --> undefined console.log('4-->', getVal( data, '' )) // --> undefined // thanks to pilchard comment console.log('5-->', getVal( data, 'stats/xxx/1' )) // --> undefined .as-console-wrapper {max-height: 100% !important;top: 0;} .as-console-row::after {display: none !important;}PO: si quiero cambiarlo a 10. Probaré a ver si puedo hacerlo con este método
tal vez eso ?
uso 1: obtener el valor
let val = onElm( data, 'stats/attack' )uso 2: cambie el valor (a 10)
let val = onElm( data, 'stats/attack', 10 )Manifestación;
const data = { id_ : '1' , name : 'Enemy x' , image : 'image.png' , stats: { level : 1 , attack : 5 , defense : 0 } } const onElm = ( obj, path, newVal=null ) => path.split('/').reduce((o,p,i,{length:n}) => (++i<n) ? o[p] : newVal ? o[p] = newVal : o[p], obj) console.log('get value of "stats/attack"\n return value ->' , onElm( data, 'stats/attack' ) ) // return value -> 5 console.log('change value of "stats/attack to 10"\n return value ->' , onElm( data, 'stats/attack', 10) ) // return value -> 10 console.log ( '\nverify data Object now with new value: \n', data ) .as-console-wrapper {max-height: 100% !important;top: 0;} .as-console-row::after {display: none !important;}Puede usar lodash zipObjectDeep para lograrlo, pero la ruta funciona a través de '.', por lo que debe
const edit = 'stats/attack'; const path = edit.split('/').join('.') zipObjectDeep([path], [1]);Reemplace todos / con . luego eval la cadena que representa obj.this.that .
Bonificación: esto también funciona para matrices "stats/level[2]/other"
var obj = { "id_": "1", "name": "Enemy x", "image": "image.png", "stats": { "level": 1, "attack": 5, "defense": 0 } }; var path = "stats/level"; var value = (eval ("obj." + path.replace(/\//g, "."))); console.log(value)