Как структурировать массив объектов, записав в подмассивы объекты, в зависимости от определённого свойства?
Есть такой массив:
[
{"value": "A", "level": 0},
{"value": "B", "level": 1},
{"value": "C", "level": 1},
{"value": "D", "level": 2},
{"value": "F", "level": 2},
{"value": "G", "level": 1},
{"value": "H", "level": 0},
{"value": "J", "level": 1},
{"value": "K", "level": 1},
{"value": "L", "level": 0},
{"value": "M", "level": 0},
{"value": "N", "level": 1},
{"value": "P", "level": 1}
];
Как вложить объекты в подмассивы по свойствам level, в случае, если это свойство увеличивается? Вот пример результата для наглядности:
[
[
{"value": "A", "level": 0},
[
{"value": "B", "level": 1},
{"value": "C", "level": 1},
[
{"value": "D", "level": 2},
{"value": "F", "level": 2}
],
{"value": "G", "level": 1}
]
],
[
{"value": "H", "level": 0},
[
{"value": "J", "level": 1},
{"value": "K", "level": 1}
]
],
[
{"value": "L", "level": 0}
],
[
{"value": "M", "level": 0},
[
{"value": "N", "level": 1},
{"value": "P", "level": 1}
]
]
];
Ответы (2 шт):
Конечно можно этот код упростить, но как быстрое решение пойдет.
const LIST = [
{"value": "A", "level": 0},
{"value": "B", "level": 1},
{"value": "C", "level": 1},
{"value": "D", "level": 2},
{"value": "F", "level": 2},
{"value": "G", "level": 1},
{"value": "H", "level": 0},
{"value": "J", "level": 1},
{"value": "K", "level": 1},
{"value": "L", "level": 0},
{"value": "M", "level": 0},
{"value": "N", "level": 1},
{"value": "P", "level": 1}
];
const LIST_NEW = [];
LIST.forEach(item => {
const LENGTH = LIST_NEW.length;
if (item.level === 0) {
LIST_NEW.push([
item,
]);
} else if (item.level === 1) {
if (!LIST_NEW[LENGTH - 1][1]) {
LIST_NEW[LENGTH - 1].push([]);
}
LIST_NEW[LENGTH - 1][1].push(item);
} else if (item.level === 2) {
let levelLength = LIST_NEW[LENGTH - 1][1].length;
if (!Array.isArray(LIST_NEW[LENGTH - 1][1][levelLength - 1])) {
LIST_NEW[LENGTH - 1][1].push([]);
}
levelLength = LIST_NEW[LENGTH - 1][1].length;
LIST_NEW[LENGTH - 1][1][levelLength - 1].push(item);
}
});
console.log(LIST_NEW);
Ход мыслей:
Невозможно написать код, не понимая, что от вас требуется. Поэтому хорошо бы сперва по пунктам написать, что должен делать код.
• Циклом бежать по массиву объектов, каждый из которых имеет свойство-уровень. При этом создать второй массив (result), куда будут добавляться все объекты.
• Если уровень равен нулю, забыть всё и добавить новый массив в result.
• При увеличении уровня, создать новый массив и вставить его в текущий,
• При уменьшении уровня, выйти из текущего массива, вставить объект в родительский массив,
• Уровень не изменился: Вставить объект в текущий массив.
Т.е. надо как-то научиться запоминать все создаваемые вложенные массивы: Можно создать массив (стек). При вставке нового массива (увеличении уровня), добавить ссылку на него в стек. При уменьшении уровня: Удалить последний элемент из стека. В итоге он всегда будет хранить последовательную цепочку вложенных массивов.
let arr = getArr();
let result = [];
let memory = [];
let curr_lvl = 0;
let curr_arr = null;
for (let i = 0; i < arr.length; i++) {
let obj = arr[i];
let last = memory.length - 1;
/* Формально, last и curr_lvl всегда равны. Но приятнее, когда для каждой цели
есть своя переменная. memory[last] выглядит понятнее, чем memory[curr_lvl] */
if (obj.level === 0) {
curr_arr = [];
memory = [curr_arr];
result.push(curr_arr);
} else if (obj.level > curr_lvl) {
curr_arr = [];
memory[last].push(curr_arr);
memory.push(curr_arr);
} else if (obj.level < curr_lvl) {
curr_arr = memory[last - 1];
memory.pop();
} else if (obj.level === curr_lvl) {
curr_arr = memory[last];
}
curr_arr.push(obj);
curr_lvl = obj.level;
}
console.log(JSON.stringify(result, null, 2).replace(/{(.|\s)*?}/g, m => m.replace(/\s+/g, "")));
/***/
function getArr() {
return [
{"value": "A", "level": 0},
{"value": "B", "level": 1},
{"value": "C", "level": 1},
{"value": "D", "level": 2},
{"value": "F", "level": 2},
{"value": "G", "level": 1},
{"value": "H", "level": 0},
{"value": "J", "level": 1},
{"value": "K", "level": 1},
{"value": "L", "level": 0},
{"value": "M", "level": 0},
{"value": "N", "level": 1},
{"value": "P", "level": 1},
];
}