Tengo un objeto json:
json = { "array": [80, 50] } Un jsoneditor de terceros devuelve una variable de ruta como una lista de cadenas o un índice del valor. Utilizo detectores de eventos para detectar cambios en el valor y almaceno esos cambios en un objeto separado para luego enviarlos a un formulario.
Por ejemplo, si cambio 50 a 60 , esto es lo que devuelve:
node.path = ["array", 1] node.value = 60 Estoy usando reduceRight() para asignar normalmente los cambios al objeto al objeto changed , sin embargo, cuando el valor es una matriz, está convirtiendo la matriz en un objeto.
let delta = node.path.reduceRight((obj, elem) => ({[elem]: obj}), node.value) //returns delta = {array: {1: 60}} //instead of delta = {array: [80, 60]} ¿Cómo puedo verificar el json original y si el campo es un objeto Array, no lo reduzca a un objeto sino que mantenga el Array original y actualice el Array con el valor modificado dentro del Array? Necesito enviar toda la matriz en el formulario.
EDITAR: sé que puedo hacer algo de lógica personalizada dentro de la reducción para verificar el json original y obtener la parte unchanged de la matriz. simplemente no se como lograr eso
let delta = node.path.reduceRight( function (obj, elem) { //some logic here to account for arrays and get original array list and change only slected index else { return {[elem]: obj}), node.value } }); EDITAR: Alternativamente, ¿cómo puedo obtener las claves anidadas de node.path y encontrar la matriz original y luego simplemente actualizar el índice de la matriz? La ruta a veces se puede anidar, por lo que la ruta siempre será la estructura tipo Array.
//this does not work let orig_key_val = json[node.path]¡Gracias!
Esto parece funcionar, finalmente... Utilicé un reduce() regular y verifiqué si la clave es una matriz si almacena mi matriz original en un objeto tmp y guardo esa clave. La próxima vez que aparezca reduce() , si el index está en el último elemento de la ruta, establezca tmp[tmp_key][key] en mi valor objetivo y devuelva el objeto Array ajustado en su lugar.
Puedo ver cómo esto no funcionará para objetos json anidados, pero por ahora no tengo ninguno... A menos que alguien pueda mostrarme cómo resolverlo, esta es mi implementación por ahora.
let tmp = {}; let tmp_key; let delta = node.path.reduce((val, key, index, array) => { if (Array.isArray(json[key])) { tmp[key] = json[key] tmp_key = key; } else if (Object.keys(tmp).length !== 0 && index === node.path.length-1) { tmp[tmp_key][key] = node.value; return tmp } else return {[key]: val} }, node.value);