2013-10-04 2 views
0

У меня есть ситуация, когда мне нужно закрепить два объекта вместе, сохраняя оба значения. Я могу перебирать оба объекта и строить массив всех ключей.Получение вложенного значения объектов из массива вложенных свойств

var traverse = function (obj, chain) { 

     for (var prop in obj) { 
      if (obj.hasOwnProperty(prop)) { 

       var tempChain = [].concat(chain || []); 
       tempChain.push(prop); 

       if (typeof obj[prop] === 'object') { 
        traverse(obj[prop], tempChain); 
       } 
       console.log(tempChain); 
      } 
     } 
    }; 

Переходя в следующем:

traverse({ 
     'a': { 
      'b': 'hello world', 
      'b1': 'hello world 1', 
      'c': { 
       'd': 'dello' 
      } 
     } 
    }) 

Вернет меня:

[a] 
[a,b] 
[a,b1] 
[a,c] 
[a, c, d] 

Так теперь у меня есть массив вложенных свойств в объекте. Как я могу получить доступ к объектам obj [[a, c, d]]? Я знаю, что могу решить проблему через eval, но я не могу доверять контенту.

eval('window.' + ['a','c','d'].join('.')); 

Если я могу цикл по этому массиву и проверить, если свойство существует в обеих из них, а затем построить новый объект комбинированные «промелькнула» значение.

+0

'окно == obj', что не будет работать в любом случае. Но да, вы можете использовать простой цикл. – Bergi

+0

Проверьте [любой из этих дубликатов] (http://stackoverflow.com/a/14397052/1048572) - просто опустите '.split (". ")', Поскольку у вас уже есть массив – Bergi

+0

Я думаю, что это своего рода [Проблема XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Что именно должен делать ваш 'zip', и зачем вам нужны цепи свойств? – Bergi

ответ

1

Возможно, что-то вроде этого?

function getValueAt(obj, keyPathArray) { 
    var emptyObj = {}; 

    return keyPathArray.reduce(function (o, key) { 
     return (o || emptyObj)[key]; 
    }, obj); 
} 

Затем вы можете использовать его как:

var o = { a: { c: { d: 1 } } }; 

getValueAt(o, ['a', 'c', 'd']); //1 

Однако это не является эффективным для несуществующих свойств, так как он не будет короткого замыкания. Вот еще один подход без использования reduce:

function getValueAt(o, keyPathArray) { 
    var i = 0, 
     len = keyPathArray.length; 

    while (o != null && i < len) o = o[keyPathArray[i++]]; 

    return o;  
} 
+0

Почему не просто 'while (o! = Null && i Bergi

+0

Я попытался использовать оба ваших решения, однако функция возвращает значение, и я хочу, чтобы объект указывал на значение. Чтобы дать лучшее объяснение, есть рабочий код, который использует evals. http://jsbin.com/EHeFayu/7/ – dtsn

+0

@Bergi, Да, почему-то я не утверждал, что последнее значение может быть объектом и что typeof 'null' был« объектом ». Глупые ошибки. Исправлена. – plalx

Смежные вопросы