Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 27.07.2014, 12:10
Интересующийся
Отправить личное сообщение для Patr56 Посмотреть профиль Найти все сообщения от Patr56
 
Регистрация: 27.07.2014
Сообщений: 10

Преобразование ТАБЛИЦЫ с родителями в json объекты
Приветствую, стоит задача передать в ext js Tree json с дочерними элементами из БД. Есть такой код, который задачу выполняет, но я не пойму как он работает, прошу знающих людей объяснить что происходит
в массив O один раз присваивается объект, затем работа идет с объектом temp, как происходит так, что в массиве O под конец выполнения функции находится вся структура?
var _makeTree = function(options) {
    var children, e, id, o, pid, temp, _i, _len, _ref;
    id = options.id || "id";
    pid = options.parentid || "parentid";
    children = options.children || "children";
    temp = {};
    o = [];
    _ref = options.q;
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
	//console.log(_i);

        e = _ref[_i];
		//console.log(e);
        e[children] = [];
        temp[e[id]] = e;
        if (temp[e[pid]] != null) {
		    
            temp[e[pid]][children].push(e);
        } else {
			//console.log('o.push(e);');
            o.push(e);
        }
    }
    return o;
};

var test =_makeTree({ q:
    [
        {"id": 123, "parentid": 0, "name": "Mammals"},
        {"id": 456, "parentid": 123, "name": "Dogs"},
        {"id": 214, "parentid": 456, "name": "Labradors"},
        {"id": 810, "parentid": 456, "name": "Pugs"},
        {"id": 919, "parentid": 456, "name": "Terriers"}
    ]
});
console.log(test);
/*
[{"id":123,"parentid":0,"name":"Mammals","children": [{"id":456,"parentid":123,"name":"Dogs","children":[{"id":214,"parentid":456,"name":"Labradors","children":[]},{"id":810,"parentid":456,"name":"Pugs","children":[]},{"id":919,"parentid":456,"name":"Terriers","children":[]}]}]}]


*/
Ответить с цитированием
  #2 (permalink)  
Старый 27.07.2014, 22:43
Аватар для ixth
Профессор
Отправить личное сообщение для ixth Посмотреть профиль Найти все сообщения от ixth
 
Регистрация: 19.01.2010
Сообщений: 354

Код писал сумрачный гений, который считает названия типа _i, _len, o само собой разумеющимися. Перевожу телепатически:
function _makeTree(options) {
    var id = options.id || "id";
    var parentid = options.parentid || "parentid";
    var children = options.children || "children";
    var itemsById = {};
    var result = [];
    var stack = options.q;
    for (var i = 0, l = stack.length; i < l; i++) {
        var item = stack[i];
        item[children] = [];
        itemsById[item[id]] = item;
        if (itemsById[item[parentid]] != null) {
            itemsById[item[parentid]][children].push(item);
        } else {
            result.push(item);
        }
    }
    return result;
}


Небольшую неясность вносит также то, что во входящей структуре q и в результате в качестве имен свойств 'id', 'parentid' и 'children' можно использовать произвольные строки, переданные в options. Это местами превращает код в череду вложенных квадратных скобок вместо нормальных обращений к свойствам.

Последний раз редактировалось ixth, 27.07.2014 в 22:55.
Ответить с цитированием
  #3 (permalink)  
Старый 27.07.2014, 22:59
Аватар для ixth
Профессор
Отправить личное сообщение для ixth Посмотреть профиль Найти все сообщения от ixth
 
Регистрация: 19.01.2010
Сообщений: 354

Кстати, код ломается на несортированном массиве. Т.е. вот такой вызов отдает уже не дерево:
var test =_makeTree({ q:
    [
        {"id": 456, "parentid": 123, "name": "Dogs"},
        {"id": 123, "parentid": 0, "name": "Mammals"},
    ]
});
Ответить с цитированием
  #4 (permalink)  
Старый 28.07.2014, 10:01
Интересующийся
Отправить личное сообщение для Patr56 Посмотреть профиль Найти все сообщения от Patr56
 
Регистрация: 27.07.2014
Сообщений: 10

Я наверно не понимаю элементарных вещей, но почему result в итоге содержит всю структуру(при отсортированном массиве)? мы один раз помещаем в него элемент item, при первом проходе цикла, как вся остальная структура children заполняется? подразумеваю что дело в ссылках на объект.
Ответить с цитированием
  #5 (permalink)  
Старый 28.07.2014, 11:25
Аватар для ixth
Профессор
Отправить личное сообщение для ixth Посмотреть профиль Найти все сообщения от ixth
 
Регистрация: 19.01.2010
Сообщений: 354

Да. На первом шаге итерации Mammals добавляется в itemsById. В itemsById ищется родитель для Mammals, но т.к. в itemsById пока что есть только Mammals, а элемента с id == 0 вообще нет в исходном наборе, то срабатывает else и Mammals попадает в result. На втором шаге все повторяется до проверки. Для Dogs в itemsById находится родитель — это Mammals. Далее в Mammals.children пушится Dogs. Цикл повторяется.

Объекты в js передаются только по ссылке. И когда в цикле в первый раз делается itemsById[item[parentid]][children].push(item), это эквивалентно result[0][children].push(item), потому что и result[0] и itemsById[item[parentid]] ссылаются на Mammals.
Ответить с цитированием
  #6 (permalink)  
Старый 28.07.2014, 12:30
Интересующийся
Отправить личное сообщение для Patr56 Посмотреть профиль Найти все сообщения от Patr56
 
Регистрация: 27.07.2014
Сообщений: 10

ixth,
Благодарю за помощь
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Преобразование русских символов в JSON maternik Серверные языки и технологии 1 04.04.2014 07:20
JSON - отобразить данные таблицы oracle / mssql / mysql ecivgamer Javascript под браузер 3 14.11.2012 18:17
Преобразование URL в JSON mikeles Events/DOM/Window 1 06.03.2011 12:38
Преобразование данных json в массив LA_ Общие вопросы Javascript 4 28.10.2010 23:54
Преобразование данных с сервера в JSON frolvict Общие вопросы Javascript 1 04.04.2010 12:26