#javascript #reactjs
#javascript #reactjs
Вопрос:
const levels = [
{
indexId: 'A',
level: 1,
name: 'A',
parent: '0',
},
{
indexId: 'A-A1',
level: 2,
name: 'A1',
parent: 'A',
},
{
indexId: 'A-A1-A11',
level: 3,
name: 'A11',
parent: 'A-A1',
},
{
indexId: 'A-A1-A11-A111',
level: 4,
name: 'A111',
parent: 'A-A1-A11',
},
{
indexId: 'A-A1-A11-A112',
level: 4,
name: 'A112',
parent: 'A-A1-A11',
},
{
indexId: 'A-A1-A12',
level: 3,
name: 'A12',
parent: 'A-A1',
},
{
indexId: 'A-A1-A12-A121',
level: 4,
name: 'A121',
parent: 'A-A1-A12',
},
{
indexId: 'A-A1-A12-A121-A1211',
level: 5,
name: 'A1211',
parent: 'A-A1-A12-A121',
},
{
indexId: 'A-A2',
level: 2,
name: 'A2',
parent: 'A',
},
{
indexId: 'A-A2-A21',
level: 3,
name: 'A21',
parent: 'A-A2',
},
{
indexId: 'A-A2-A22',
level: 3,
name: 'A22',
parent: 'A-A2',
},
{
indexId: 'A-A3',
level: 2,
name: 'A3',
parent: 'A',
},
{
indexId: 'A-A3-A31',
level: 3,
name: 'A31',
parent: 'A-A3',
},
{
indexId: 'A-A3-A32',
level: 3,
name: 'A32',
parent: 'A-A3',
},
]
const maxLevel = levels.filter(
l => l.level === Math.max(...levels.map(l => l.level))
)
const arrayStrings = []
function stackLetter(l) {
for (let index = 1; index <= l.length; index ) {
arrayStrings.push(l.slice(0, index))
}
}
stackLetter(maxLevel[0].indexId.split('-'))
console.log(arrayStrings)
const buildTree = arrayStrings
.map(arr => arr.join('-'))
.map(s => {
return levels.filter(l => l.indexId === s)
})
console.log(buildTree)
Изначально я получил самую длинную ветвь с максимальным уровнем
output array = [["A"],["A-A1"],["A-A1-A12"],["A-A1-A12-A121"],["A-A1-A12-A121-A1211"]]
если я выбираю indexId = ‘A-A1-A12’>, я получаю [[«A»], [«A-A1»], [«A-A1-A12»] ]
но ожидаемый результат — это код, который может быть любой ветвью, связанной с выбранным мной узлом, это может быть =
[[«A»],[«A-A1»], [«A-A1-A12»], [«A-A1-A12-A121»], [«A-A1-A12-A121-A1211»]]
или, если я выберу ‘A-A3’, это должно дать
[[«A»],[«A-A3»],[«A-A3-A31»]]
или
[[«A»],[«A-A3»],[«A-A3-A32»]]
Комментарии:
1. Вы уже пробовали что-то самостоятельно относительно выбора?
2. Пожалуйста, укажите больше ожидаемого результата. Для
'A-A3'
выбора вы хотите[["A"],["A-A3"],["A-A3-A31"]] or [["A"],["A-A3"],["A-A3-A32"]]
. Что означает или ? Один из них, не имеет значения, какой? Первое? Оба?3. поскольку A3 имеет два дочерних элемента A31 и A32, поэтому or означает, что он может предоставить любой из них, да, я пробовал, но я пробовал использовать функцию stackLetter, если я выбираю узел с индексом id = A-A31, я получаю [[«A»], [«A-A3»]] не его дочерние узлы, сравнение идентификатора индекса с индексом обхода узлов или с родительским идентификатором даст мне еще 1 дочерний узел, но более глубокие узлы, как я упоминал выше.
Ответ №1:
Следующий код выводит то, что требуется в OP. Это reduce
исходный массив, «запоминающий» до сих пор «самый глубокий» id
и level
. Если для обработанного item
level
не является непрерывным или indexId
не соответствует selection
или «запоминается» id
, он не добавляется в выходной массив.
Возвращаемая ветвь является «первой по глубине», то есть первой, которую она находит, не обязательно самой глубокой.
const levels = [
{
indexId: 'A',
level: 1,
name: 'A',
parent: '0',
},
{
indexId: 'A-A1',
level: 2,
name: 'A1',
parent: 'A',
},
{
indexId: 'A-A1-A11',
level: 3,
name: 'A11',
parent: 'A-A1',
},
{
indexId: 'A-A1-A11-A111',
level: 4,
name: 'A111',
parent: 'A-A1-A11',
},
{
indexId: 'A-A1-A11-A112',
level: 4,
name: 'A112',
parent: 'A-A1-A11',
},
{
indexId: 'A-A1-A12',
level: 3,
name: 'A12',
parent: 'A-A1',
},
{
indexId: 'A-A1-A12-A121',
level: 4,
name: 'A121',
parent: 'A-A1-A12',
},
{
indexId: 'A-A1-A12-A121-A1211',
level: 5,
name: 'A1211',
parent: 'A-A1-A12-A121',
},
{
indexId: 'A-A2',
level: 2,
name: 'A2',
parent: 'A',
},
{
indexId: 'A-A2-A21',
level: 3,
name: 'A21',
parent: 'A-A2',
},
{
indexId: 'A-A2-A22',
level: 3,
name: 'A22',
parent: 'A-A2',
},
{
indexId: 'A-A3',
level: 2,
name: 'A3',
parent: 'A',
},
{
indexId: 'A-A3-A31',
level: 3,
name: 'A31',
parent: 'A-A3',
},
{
indexId: 'A-A3-A32',
level: 3,
name: 'A32',
parent: 'A-A3',
},
]
// auxiliary function to compare if 1st string starts with the second one or vice versa (according to legth)
function stringMatch(s1,s2) {
return s1.length > s2.length ? s1.startsWith(s2) : s2.startsWith(s1);
}
// main function
function extract(input,selection="") {
var id = "", level = 0; // initial conditions, storing "last" added item data
return input.reduce((answer,item) => { // loop the input array and reduce it ...
// do nothing (return unchenged answer) if ...
if (item.level !== level 1) return answer; // ... level is not plus one from current level
if (!item.indexId.startsWith(id)) return answer; // ... indexId does not start with current id
if (!stringMatch(item.indexId,selection)) return answer; // ... item.indexId does not fit selection
// update "last" data
level = item.level;
id = item.indexId;
// return updated answer
return [...answer,id];
},[]); // reduction starts from empty array
}
// test
console.log(extract(levels));
// [ 'A', 'A-A1', 'A-A1-A11', 'A-A1-A11-A111' ]
console.log(extract(levels,"A-A2"));
// [ 'A', 'A-A2', 'A-A2-A21' ]
console.log(extract(levels,"A-A3"));
// [ 'A', 'A-A3', 'A-A3-A31' ]