1

Предположим, что мне нужен словарь JavaScript (объект/ассоциативный массив), который мне нужно получить доступ к следующим образом:Предпочтительный способ создания «словаря словарей» в JavaScript

var value = dict[foo][bar][buz][qux]; // this could go on 

Что является лучшим способом для инициализации этого Словарь? Единственный способ, который я могу придумать, это:

// 'foo', 'bar', 'baz', 'qux' are variables 
var dict = {}; 
dict[foo] = {}; 
dict[foo][bar] = {}; 
dict[foo][bar][buz] = {}; 
dict[foo][bar][buz][qux] = value; 

В качестве альтернативы, есть ли лучший способ достичь тех же результатов? Я бы предпочел решение, которое работает как в браузерах, так и в Node.js.

ответ

1

Опцион заключается в создании объекта динамически, как:

var vals = [1, 2, 3, 4]; 

function createObject(arr) { 
    var obj = {}; 
    var mod = obj; 
    for (var i = 0, j = arr.length; i < j; i++) { 
     if (i === (j - 1)) { 
      mod.value = arr[i]; 
     } else { 
      mod[arr[i]] = {}; 
      mod = mod[arr[i]]; 
     } 
    } 
    return obj; 
} 

console.log(createObject(vals)); 

DEMO:http://jsfiddle.net/BnkPz/

Таким образом, ваш список переменных должны быть помещены в массив и передаются функции, или функция может изменить для работы с любым количеством переданных аргументов.

+0

Это, кажется, самое приятное решение, я, вероятно, соглашусь с ним. – adrianp

+0

@adrianp Примите все, что лучше всего подходит для вас. Ваш первоначальный вопрос был немного запутанным, поэтому, пока решение работает для вас и работает хорошо, пойдите с этим. Задайте любые вопросы, если вы хотите больше узнать о решении – Ian

1

Вы можете просто определить его в одной строке:

var dict = { foo: { bar: { buz: {qux: "value"}}}}; 


Использование JSON.parse

var dict = JSON.parse('{ "' + foo + '": { "' + bar + '": { "' + buz + '": { "' + qux + '": "value"}}}}'); 
+1

Если 'bar' является переменной, это не сработает. – adrianp

+0

@adrianp Вы должны отредактировать исходный вопрос, чтобы включить это требование. –

+0

@ThomasIngham Я сделал. – adrianp

0

Вы можете создать функцию, которая принимает объект для изменения, путь к свойству листа (дот-разделителями строку, как foo + '.' + bar + '.' + buz + '.' + qux), и значение, и зациклить его и сделать работу для вас:

var foo = 'foo', 
    bar = 'bar', 
    buz = 'buz', 
    qux = 'qux', 
    path = foo + '.' + bar + '.' + buz + '.' + qux, 
    dict = {}; 

createNestedProperty(dict, path, 10); 
console.log(dict); 

function createNestedProperty(dict, path, value) { 
    var pathArray = path.split('.'), 
     current; 
    while(pathArray.length) { 
     current = pathArray.shift(); 
     if(!dict.hasOwnProperty(current)) { 
      if(pathArray.length) { 
       dict[current] = {}; 
      // last item 
      } else { 
       dict[current] = value;  
      } 
     } 
    } 
} 

http://jsfiddle.net/NuqtM/

Кроме того, подобный вопрос был задан здесь: Extend a JavaScript object by passing a string with the path and a value.

+0

Хотя это решение выполняет свою работу, меня немного беспокоит его «ремонтопригодность» (для тех, кто наследует мой проект). – adrianp

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