Propiedad establecida dinámicamente del objeto anidado

Resuelto John B. asked hace 11 años • 28 respuestas

Tengo un objeto que podría tener cualquier cantidad de niveles de profundidad y podría tener cualquier propiedad existente. Por ejemplo:

var obj = {
    db: {
        mongodb: {
            host: 'localhost'
        }
    }
};

Sobre eso me gustaría establecer (o sobrescribir) propiedades de esta manera:

set('db.mongodb.user', 'root');
// or:
set('foo.bar', 'baz');

Donde la cadena de propiedad puede tener cualquier profundidad y el valor puede ser cualquier tipo/cosa.
No es necesario fusionar los objetos y matrices como valores, si la clave de propiedad ya existe.

El ejemplo anterior produciría el siguiente objeto:

var obj = {
    db: {
        mongodb: {
            host: 'localhost',
            user: 'root'
        }
    },
    foo: {
        bar: baz
    }
};

¿Cómo puedo realizar tal función?

John B. avatar Sep 22 '13 02:09 John B.
Aceptado

Esta función, utilizando los argumentos que especificó, debería agregar/actualizar los datos en el objcontenedor. Tenga en cuenta que debe realizar un seguimiento de qué elementos del objesquema son contenedores y cuáles son valores (cadenas, entradas, etc.); de lo contrario, comenzará a generar excepciones.

obj = {};  // global object

function set(path, value) {
    var schema = obj;  // a moving reference to internal objects within obj
    var pList = path.split('.');
    var len = pList.length;
    for(var i = 0; i < len-1; i++) {
        var elem = pList[i];
        if( !schema[elem] ) schema[elem] = {}
        schema = schema[elem];
    }

    schema[pList[len-1]] = value;
}

set('mongo.db.user', 'root');
bpmason1 avatar Sep 21 '2013 20:09 bpmason1

Lodash tiene un método _.set() .

_.set(obj, 'db.mongodb.user', 'root');
_.set(obj, 'foo.bar', 'baz');
aheuermann avatar Jul 27 '2016 15:07 aheuermann