Javascript Array of Objects реструктуризация - PullRequest
0 голосов
/ 01 декабря 2018

Я получаю данные из реляционной базы данных, объединив 3 таблицы:

var btnObj2 = [
{sect_id: 1, sect_title: 'Navigation', subsect_id: 1, subsect_title:'Übersicht', btn_id: 1, btn_title: 'Inhaltsverzeichnis'},
{sect_id: 1, sect_title: 'Navigation', subsect_id: 1, subsect_title: 'Übersicht', btn_id: 2, btn_title: 'Stichwortverzeichnis'},
{sect_id: 1, sect_title: 'Navigation', subsect_id: 2, subsect_title: 'Praxisphasen', btn_id: 3, btn_title: 'Trainingserfolg'},
{sect_id: 1, sect_title: 'Navigation', subsect_id: 2, subsect_title: 'Praxisphasen', btn_id: 4, btn_title: 'Trainingsablauf'},
{sect_id: 2, sect_title: 'Modul 1', subsect_id: 3, subsect_title: 'Mentor-Gespräche', btn_id: 5, btn_title: 'Lebenszeit'},
{sect_id: 2, sect_title: 'Modul 1', subsect_id: 3, subsect_title: 'Mentor-Gespräche', btn_id: 6, btn_title: 'Lebensplanung'},
{sect_id: 2, sect_title: 'Modul 1', subsect_id: 4, subsect_title: 'Just do it', btn_id: 7, btn_title: 'Vertrauen'},
{sect_id: 2, sect_title: 'Modul 1', subsect_id: 4, subsect_title: 'Just do it', btn_id: 8, btn_title: 'Verantwortung'}
];

Эти данные должны быть реструктурированы таким образом, чтобы каждый раздел содержал свои подразделы, а каждый подраздел содержал свои подподразделы (subsub-подразделы - кнопки в фрагменте кода выше).Данные из базы данных уже возвращены в правильном порядке в соответствии с разделами, подразделами, подразделами.

Вывод должен быть таким, как показано ниже:

var result = [
{
    sect_id: 1,
    sect_title: 'Navigation',
    subsect: [
        {
            subsect_id: 1,
            subsect_title: 'Übersicht',
            buttons: [
                {
                    btn_id: 1,
                    btn_title: 'Verantwortung'
                },
                {
                    btn_id: 2,
                    btn_title: 'Vertrauen'
                }
            ]
        },
        {
            subsect_id: 2,
            subsect_title: 'Praxisphasen',
            buttons: [
                {
                    btn_id: 3,
                    btn_title: 'Trainingserfolg'
                },
                {
                    btn_id: 4,
                    btn_title: 'Trainingsablauf'
                }
            ]
        }
    ]
},
sect_id: 2,
sect_title: 'Module 1',
//.....
];

Вот как ясделал бы это PHP-способом:

function prepareBtns(arr) {
    var sectId, subsectId = ''
    var newArr = []
    arr.forEach((item) => {
        if(sectId !== item.sect_id){
            sectId = item.sect_id
        }
        if(subsectId !== item.subsect_id){
            subsectId = item.subsect_id
        }
        //In PHP the following line does the Job
        newArr[sectId][subsectId][] = item
    })
    return newArr
}

Это одно из моих испытаний JS.Это привело к пустым слотам:

function prepareBtnsXY(arr) {
var newArr = [];
arr.forEach((item) => {
    if (!newArr[item.sect_id]) {

        var objToPush = {
            sectId: item.sect_id,
            sectName: item.sect_title,
            subsect: []
        };
        newArr[item.sect_id] = objToPush;
    }

    if (!newArr[item.sect_id].subsect[item.subsect_id]) {
        var subObjToPush = {
            subsectId: item.subsect_id,
            subsectName: item.subsect_title,
            buttons: []
        };
        newArr[item.sect_id].subsect[item.subsect_id] = subObjToPush;
    }

    if (!newArr[item.sect_id].subsect[item.subsect_id].buttons[item.btn_id]) {
        var btnObjToPush = {
            btnId: item.btn_id,
            btnName: item.btn_title
        };
        newArr[item.sect_id].subsect[item.subsect_id].buttons[item.btn_id] = btnObjToPush;
    }
});

return newArr
}

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

Вы можете сохранить нужные ключи в другом массиве, где первый ключ каждой строки является значением ключа для группировки, следующие ключи являются ключами данных для этого уровня, а последний ключ предназначен для дочерних / подуровней.Конечный массив не содержит дочерних значений, но заполнитель undefined.

keys = [
  //  level key          level  properties        children
  // ------------  ----------------------------- ----------
    ['sect_id',    'sect_title' /* more keys */, 'subsect'],
    ['subsect_id', 'subsect_title',              'buttons'],
    ['btn_id',     'btn_title',                  undefined]
],

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

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

var data = [{ sect_id: 1, sect_title: 'Navigation', subsect_id: 1, subsect_title: 'Übersicht', btn_id: 1, btn_title: 'Inhaltsverzeichnis' }, { sect_id: 1, sect_title: 'Navigation', subsect_id: 1, subsect_title: 'Übersicht', btn_id: 2, btn_title: 'Stichwortverzeichnis' }, { sect_id: 1, sect_title: 'Navigation', subsect_id: 2, subsect_title: 'Praxisphasen', btn_id: 3, btn_title: 'Trainingserfolg' }, { sect_id: 1, sect_title: 'Navigation', subsect_id: 2, subsect_title: 'Praxisphasen', btn_id: 4, btn_title: 'Trainingsablauf' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 3, subsect_title: 'Mentor-Gespräche', btn_id: 5, btn_title: 'Lebenszeit' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 3, subsect_title: 'Mentor-Gespräche', btn_id: 6, btn_title: 'Lebensplanung' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 4, subsect_title: 'Just do it', btn_id: 7, btn_title: 'Vertrauen' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 4, subsect_title: 'Just do it', btn_id: 8, btn_title: 'Verantwortung' }],
    keys = [['sect_id', 'sect_title', 'subsect'], ['subsect_id', 'subsect_title', 'buttons'], ['btn_id', 'btn_title', undefined]],
    result = data.reduce((r, o) => {
        keys.reduce((a, k) => {
            var temp = a.find(p => o[k[0]] === p[k[0]]);
            if (!temp) {
                a.push(temp = Object.assign(
                    ...k.map((l, i, { length }) =>
                        l && { [l]: i + 1 === length ? [] : o[l] })
                ));
            }
            return temp[k[k.length - 1]];
        }, r);
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 01 декабря 2018

Вы можете получить желаемый результат примерно так:

let r = {}, data = [{ sect_id: 1, sect_title: 'Navigation', subsect_id: 1, subsect_title: 'Übersicht', btn_id: 1, btn_title: 'Inhaltsverzeichnis' }, { sect_id: 1, sect_title: 'Navigation', subsect_id: 1, subsect_title: 'Übersicht', btn_id: 2, btn_title: 'Stichwortverzeichnis' }, { sect_id: 1, sect_title: 'Navigation', subsect_id: 2, subsect_title: 'Praxisphasen', btn_id: 3, btn_title: 'Trainingserfolg' }, { sect_id: 1, sect_title: 'Navigation', subsect_id: 2, subsect_title: 'Praxisphasen', btn_id: 4, btn_title: 'Trainingsablauf' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 3, subsect_title: 'Mentor-Gespräche', btn_id: 5, btn_title: 'Lebenszeit' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 3, subsect_title: 'Mentor-Gespräche', btn_id: 6, btn_title: 'Lebensplanung' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 4, subsect_title: 'Just do it', btn_id: 7, btn_title: 'Vertrauen' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 4, subsect_title: 'Just do it', btn_id: 8, btn_title: 'Verantwortung' } ];

while (data.length) {
  let {sect_id,sect_title,subsect_id,subsect_title,btn_id,btn_title} = data.pop(),
  subsect = {subsect_id, subsect_title, buttons: [{btn_id, btn_title}]}
		
  if(!r[sect_id]) 
    r[sect_id] = {sect_id, sect_title, subsect: [subsect]}
  else {
    let sub = r[sect_id].subsect.find(x => x.subsect_id == subsect_id)
    if(sub) sub.buttons.push({btn_id, btn_title})
    else r[sect_id].subsect.push(subsect)
  }
}

console.log(Object.values(r))

Идея состоит в том, чтобы использовать while и Array.pop, чтобы продолжать получать элементы из массива и продолжать строить дерево.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...