#json #angular #typescript
#json #angular #typescript
Вопрос:
С сервера я получаю этот объект JSON. Он представляет собой органиграмму компании и связанных с ней отделов.
Мне нужно иметь возможность выбрать компанию, и с идентификатором компании мне нужно передать в массив чисел идентификаторы связанных отделов.
Для этого я создал эту рекурсивную функцию. Это работает, но пропускает 3 отдела, которые размещены в другом отделе
Это файл JSON
{
"cd": 1,
"cd_base": 0,
"nome": "EMPRESA A",
"children": [
{
"cd": 2,
"cd_base": 1,
"nome": "Departamento A",
"children": [
{
"cd": 4,
"cd_base": 2,
"nome": "Serviço A1",
"children": []
},
{
"cd": 15,
"cd_base": 2,
"nome": "Serviço A2",
"children": []
}
]
},
{
"cd": 3,
"cd_base": 1,
"nome": "Departamento B",
"children": [
{
"cd": 7,
"cd_base": 3,
"nome": "Serviço B1",
"children": []
}
]
},
{
"cd": 186,
"cd_base": 1,
"nome": "Departamento XX",
"children": []
}
]
}
И это функция в Typescript
recursiveFunction(res: any): any[] {
const numbers = new Array(); // to store the ID
console.log('Im on ' res.cd ' | ' res.nome);
numbers.push(res.cd);
if (res.children.length > 0) {
console.log(res.cd ' | ' res.nome ' has children');
res.children.forEach((row) => {
numbers.push(row.cd);
this.recursiveFunction(row);
});
} else {
console.log(res.cd ' | ' res.nome ' doesn't have any children');
}
return numbers;
}
И это возврат этой функции на консоль
Im on 1 | EMPRESA A
1 | EMPRESA A has c
Im on 2 | Departamento A
2 | Departamento A has children
Im on 4 | Serviço A1
4 | Serviço A1 doesn't have any children
Im on 15 | Serviço A2
15 | Serviço A2 doesn't have any children
Im on 3 | Departamento B
3 | Departamento B has children
Im on 7 | Serviço B1
7 | Serviço B1 doesn't have any children
Im on 186 | Departamento XX
186 | Departamento XX doesn't have any children
Затем я регистрирую массив чисел, и результатом является 1,2,3,186
this.numbers.forEach(row => {
console.log(row);
});
// 1, 2, 3, 186
Она добавляет CD 1, 2, 3 и 186, но пропускает 4, 7 и 15.
Все это ветвь / узел внутри другой ветви / узла
Чего я не понимаю? Рекурсивный способ — лучший способ сделать это? Есть ли более простой способ?
Приветствуется любая помощь
Комментарии:
1. 1. Ваша функция не является рекурсивной, потому что вы вызываете «recursiveCheckChildren» вместо «recursiveFunction». Пожалуйста, опубликуйте код «recursiveCheckChildren()», чтобы я мог показать вам проблему.
2. О, я вижу, на самом деле, это так, я изменился при написании вопроса — ‘ Я изменю вопрос. Спасибо, что указали на это
3. Вот решение вашей проблемы с рекурсивной функцией: stackblitz.com/edit/angular-cm2kqr
Ответ №1:
Это потому, что вы определили рекурсивную функцию, которая возвращает результат, но вы не используете этот результат.
Хотя ответ @aonepathan работает, я бы избегал использования переменных вне области действия вашей функции.
Вместо этого все, что вам нужно сделать, это объединить результат функции с текущим массивом:
recursiveFunction(res: any): any[] {
let numbers = new Array(); // to store the ID
console.log('Im on ' res.cd ' | ' res.nome);
numbers.push(res.cd);
if (res.children.length > 0) {
console.log(res.cd ' | ' res.nome ' has children');
res.children.forEach((row) => {
numbers = numbers.concat(this.recursiveFunction(row));
});
} else {
console.log(res.cd ' | ' res.nome ' doesn't have any children');
}
return numbers;
}
Другой вариант — передать массив чисел в вызовы вашей функции, и таким образом вы избавитесь от возврата:
recursiveFunction(res: any, numbers: any[]) {
console.log('Im on ' res.cd ' | ' res.nome);
numbers.push(res.cd);
if (res.children.length > 0) {
console.log(res.cd ' | ' res.nome ' has children');
res.children.forEach((row) => {
this.recursiveFunction(row, numbers);
});
} else {
console.log(res.cd ' | ' res.nome ' doesn't have any children');
}
}
Первый раз, когда вы бы вызвали это, был бы с новым массивом:
let result = new Array();
recursiveFunction(res, result);
doSomething(result);
Комментарии:
1. Большое спасибо! Как вы заявили, я также предпочитаю не использовать переменные вне области видимости, поэтому я выберу этот
2. согласен, переменная scoping и этот ответ более уместны!
Ответ №2:
Похоже, вы, возможно, повторно инициализировали массив чисел каждый раз, когда функция вызывается снова, рассмотрите возможность перемещения его за пределы функции:
const numbers = new Array();
function recursiveFunction(res: any): any[] {
console.log('Im on ' res.cd ' | ' res.nome);
numbers.push(res.cd);
if (res.children.length > 0) {
console.log(res.cd ' | ' res.nome ' has children');
res.children.forEach((row) => {
// numbers.push(row.cd);
this.recursiveFunction(row);
});
} else {
console.log(res.cd ' | ' res.nome ' doesn't have any children');
}
return numbers;
}
Я избавился от второго нажатия, поскольку, как только вы вызываете функцию, идентификатор помещается в массив чисел.
Консоль: 1, 2, 4, 15, 3, 7, 186
Комментарии:
1. Я немного отупел 🙂 Но спасибо. Это именно то, что мне было нужно 🙂