У меня есть входной массив, с контуром вроде
var path = ["foo","bar","baz"];
И у меня есть объект
var obj = { "foo": { "bar": { "baz": "cake" }, "notbar": { "another": "value" } } }
И я хочу изменить значение «baz» из пути. Я знаю, что могу использовать
obj[path[0]][path[1]][path[2]] = "value";
но я не знаю, как долго будет массив. и php, и javascript anwsers оценены!
Здесь идет мое не очень, но рабочее решение:
function setPropertyByPath(obj, path, value) { if(!path || path.length === 0) return; var property = path[0]; for(var i = 1; i < path.length; i++) { property += "." + path[i]; } property = "obj." + property + " = \"" + value + "\""; eval(property) }
Затем вы звоните
setPropertyByPath(obj, path, "newValue");
Здесь работает FIDDLE
Попробуй это:
function getValueByPath(obj, path) { var result = obj, i; for (i = 0; i < path.length; i++) { try { result = result[path[i]]; } catch (e) { return undefined; } } return result } function setValueByPath(obj, path, value) { var result = obj, i; for (i = 0; i < path.length - 1; i++) { try { result = result[path[i]]; } catch (e) { return; } } if (typeof value == 'object') { result[path[i]] = value; } }
Учитывая переменные инициализации, getValueByPath(obj, path)
возвращает 'cake'
, а затем устанавливает его как setValueByPath(obj, path, 'value')
; теперь getValueByPath(obj, path)
возвращает 'value'
.
Что-то вроде этого должно работать
function modify(obj, path, val) { var e = obj, l = path.pop(); path.forEach(function(x) { x in e ? e = e[x] : e; }); if (typeof val === 'undefined') return e[l]; e[l] = val; return e; }
Вы можете назвать это как геттер или сеттер
var what = modify(obj, path); // returns "cake" modify(obj, path, 'new value'); var what2 = modify(obj, path); // now return "new value", object was modified
FIDDLE