2012-08-01 2 views
1

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

Например.

Я начинаю с:

var htmlString = { 
    "div": [{ 
     "attributes": { 
      "class": "myDivClass" 
     }, 
     "p": [{ 
      "attributes": { 
       "class": "myPClass" 
      } 
     }] 
    }] 
}; 

Теперь давайте добавим что-то другое:

var htmlString = { 
    "div": [{ 
     "attributes": { 
      "class": "myDivClass" 
     }, 
     "p": [{ 
      "attributes": { 
       "class": "myPClass" 
      }, 
      "span": [{ 
       "attributes": { 
        "class": "mySpanClass" 
       } 
      }] 
     }] 
    }] 
}; 

Код я работаю над будет иметь такой же формы, как:

var childNode = document.createElement("myChildElement"); 
for (key in value) { 
    if (value.hasOwnProperty(key)) { 
     if (key == "attributes") { 
      childNode.setAttributes(myAttributes); // loop through attributes on the element 
     } 
     else { 
      //the same code ad infinitum 
      var childChildNode = document.createElement("myChildChildElement"); 
      // etc etc.... 
     } 
    } 
} 
parentNode.appendChild(childNode); 

Правила каждого дополнительного элемента одинаковы, поэтому я должен иметь возможность просто пропустить эту структуру данных так же, как и для b некоторые части кода, я просто не уверен, как, хотя я готов поспорить, что там где-то есть цикл while(). Может ли кто-нибудь сказать мне?

P.S. Ровный javascript, пожалуйста, нет jQuery! (Хотя, если у вас есть ответ YUI3, мне было бы очень интересно).

+4

В ваших примерах нет JSON, только объекты JavaScript. Мне кажется, что вам нужно создать рекурсивную функцию. –

+0

Это не тот код, над которым я работаю, но JSONLint был доволен этим как действительный JSON. И да, рекурсивная функция для этого - именно то, о чем я прошу, спасибо. – Jezcentral

+3

JSON, * формат обмена данными *, является подмножеством синтаксиса литералов объекта JavaScript, поэтому да, некоторые литералы объектов также действительны JSON, но это не делает вашу проблему иметь какое-либо отношение к JSON. Вы спрашиваете, как рекурсивно обрабатывать вложенные объекты JavaScript ... совсем не связанные с JSON. Я исправлю ваш вопрос ... –

ответ

2
var createTree = function (node, data) { 
    for (var key in data) { 
     if (data.hasOwnProperty(key)) { 
      if (key == "attributes") { 
       node.setAttributes(myAttributes); // loop through attributes on the element 
      } 
      else { 
       for (var i = 0; i < data[key].length; ++i) { 
        var childNode = document.createElement(key); 
        createTree(childNode, data[key][i]); 
        node.appendChild(childNode); 
       } 
      } 
     } 
    } 
} 

createTree(parentNode, htmlString); 
+0

Спасибо, Qnan, я проверю его, когда у меня появится такая возможность, но, глядя на это, я вижу, что вы включили переменную «данные», которая никогда не ссылается, и когда это вызывается впервые, parentNode и «div» будет ссылаться на один и тот же узел, не так ли? Тем не менее, это показывает мне, как реализовать рекурсивную функцию, поэтому спасибо за это. – Jezcentral

+0

@ пользователь1565354 извините, исправно. «данные» на самом деле ссылаются на поддерево того, что вы называете «htmlString», которое должна обрабатывать функция. В первом вызове это будет сама htmlString.«div» должен был быть верхним ключом в htmlString, а «parentNode» - это любой узел, к которому вы хотите приложить все это. – Qnan

+0

@ user1565354 На самом деле это должно выглядеть несколько иначе - см. Edit – Qnan

0

Хорошо, код Qnan нуждалась немного подправить, так как он не имел дело с получением до конца конца ветви должным образом. Как только это дошло до конца, проверить было нечего, и нулевая длина ничего не вызывала ошибку.

Я знаю, что это плохая практика, но уже поздно, и мне нужно это исправление, поэтому вот моя настройка.

var createTree = function (node, data) { 
    for (key in data) { 
     if (data.hasOwnProperty(key)) { 
      if (key == "attributes") { 
       node.setAttributes(myAttributes); // loop through attributes on the element 
      } 
      else { 
       try { 
        for (var i = 0; i < data[key].length; ++i) { 
         var childNode = document.createElement(key); 
         createTree(childNode, data[key][i]); 
         node.appendChild(childNode); 
        } 
       } 
       catch(error) { 
        console.log("there was an error"); 
       } 
      } 
     } 
    } 
} 

createTree(parentNode, htmlString); 

Да, это правильно, я похоронил ошибку, попробовав/поймав ее ... а затем ничего не делая. Не пробуйте это дома дети!

Qnan, еще раз спасибо.

+0

Это интересно. Какой вклад вы кормите, точно? Скрипка здесь http://jsfiddle.net/S6ZGK/4/ ходит по дереву точно так же, как в вашем примере, но показывает всплывающие окна вместо установки атрибутов элементов и, похоже, не вызывает никаких ошибок. – Qnan

+0

Было бы так: вар HTMLString = { "ДИВ": [{ "атрибуты": { "класс": "myDivClass" }, "р": [{ "атрибуты": { " класс ": "myPClass" }, "диапазон": [{ "атрибуты": { "класс": "mySpan" } }] }], "ДИВ": [{ "атрибуты" : { "класс": "myDiv" }, "span": [{ "attributes": { "класс": "класс2" } }] } }] }; – Jezcentral

+0

И просто, чтобы яснить, я уверен, что любые ошибки, возникающие из-за реализации кода, связаны со мной, а не с вами. :) – Jezcentral

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