0

I would like to access the object provided only it's string path in form of array is known.

1.) there is an object, where

root["obj1"]["obj2"] = 1;

(in common case root["obj1"]...["objN"])

2.) I have ONLY string objectPath known:

var objectPath = 'root["obj1"]["obj2"]'

3.) I need NOT only READ the object, but SET it's value, like

objectPath = 2;
//so root["obj1"]["obj2"] === 2

As I understand

  1. there might be some options with eval(), but it gets the value, not the variable;

  2. one can loop through all objects of root, make convertion to "root.obj1.obj2" (which is not the case, as "obj1" can easily be "obj with spaces1") and check if given string equals to current object in the loop.

http://jsfiddle.net/ACsPn/

Related Link: Access object child properties using a dot notation string

Community
  • 1
  • 1
Max
  • 1,463
  • 5
  • 19
  • 34
  • yes, with eval(), i need to reset the object, change the 1 to 2 for example. – Max May 15 '13 at 11:43
  • The accepted answer in the question you link to is much better than eval. It contains almost everything you need, you just have to use a different splitting and change it to a `set(path,value)` function. – Denys Séguret May 15 '13 at 11:46
  • one char "." against two chars "[" "]" is already some parser approach, I'm sure we can do better? – Max May 15 '13 at 11:50
  • 1
    As it's not so easy to make such a function right after all, I wrote one. See answer. – Denys Séguret May 15 '13 at 11:59

1 Answers1

0

I wrote a function for you, trying to make it as pretty and reusable as possible :

function setProp(path, newValue, holder) {
    var t = path.split(/[\[\]"]+/).filter(function(v){return v}),
        l = t.pop(), s, o = holder || window;
    while (s = t.shift()) o = o[s];
    o[l] = newValue;
}

You use it like this :

setProp('root["obj1"]["obj2"]', 2);

If your root object isn't in a global variable, pass the relevant holder as third argument.

Demonstration (open the console to see the changed root object)

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • ok, thanks for ingenious split! Could not have done it on my own. Could you explain a bit what split and filter do. PS: var s; while (s = t.shift)...? – Max May 15 '13 at 12:06
  • The filter is just here to ensure there is no empty value at one end of the array after split. [shift](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/shift) removes the first element from the array and returns it, and as `=` returns the assigned value, the loop ends when `shift` returns nothing (ie the array is empty). – Denys Séguret May 15 '13 at 12:11
  • (/[\[\]"]+/) < that was unclear, shift is ok, and by PS I meant your "s" variable is global, should not it be scoped to setProp function? – Max May 15 '13 at 12:22
  • yes, I forgot the var on s. I'll add it. The `/[\[\]"]+/` part is a regular expression matching any not empty set of the chars `[`, `]` and `"`. – Denys Séguret May 15 '13 at 12:25
  • going to go read the book on regexp, again :) have a nice day! – Max May 15 '13 at 12:38