J'ai rencontré un type de problème que je ne connais pas en javascript. Je suppose qu'il y a probablement une approche simple pour résoudre ce genre de problème, mais je ne sais pas ce que cela pourrait être.Comment activer une boucle javascript pour itérer récursivement un nombre inconnu de fois?
- J'ai un tableau qui contient une série d'objets.
- Chacun de ces objets peut (ou non) contenir un tableau plus profond contenant une série d'objets.
- Chacun de ces objets peut (ou non) contiennent un tableau plus profond qui contient une série d'objets
- (et ainsi de suite ...)
je dois traiter chaque objet dans chaque série d'objets, donc écrire un function
qui exécute un for loop
que je peux invoquer à plusieurs reprises semble l'approche évidente. Mais ... (voici le problème) ... puisque la fonction peut invoquer lui-même un nombre répété de fois, comment puis-je écrire une boucle qui continue à aller plus loin dans l'objet, aussi profond qu'il doit ?
Voici un exemple ...
Avec cet objet:
{
"level1": [
{
"FirstItem": "one",
"SecondItem": "two",
"ThirdItem": [
{
"FirstItem": "three",
"SecondItem": "four"
}
]
},
{
"FirstItem": "five",
"SecondItem": "six",
"ThirdItem": [
{
"FirstItem": "seven",
"SecondItem": "eight"
}
]
}
]
}
je peux enregistrer les valeurs dans l'ordre en utilisant cette boucle imbriquée:
for (var i = 0; i < Object.keys(myObject.level1).length; i++) {
for (var j = 0; j < (Object.values(myObject.level1[i]).length); j++) {
if (typeof Object.values(myObject.level1[i])[j] === 'string') {
console.log(Object.values(myObject.level1[i])[j]);
}
else {
for (var k = 0; k < Object.values(myObject.level1[i])[j].length; k++) {
for (var l = 0; l < (Object.values(Object.values(myObject.level1[i])[j][k]).length); l++) {
if (typeof Object.values(Object.values(myObject.level1[i])[j][k])[l] === 'string') {
console.log(Object.values(Object.values(myObject.level1[i])[j][k])[l]);
}
}
}
}
}
}
Preuve:
var myObject = {};
myObject['level1'] = [];
myObject.level1[0] = {FirstItem: 'one', SecondItem: 'two'};
myObject.level1[0]['ThirdItem'] = [];
myObject.level1[1] = {FirstItem: 'five', SecondItem: 'six'};
myObject.level1[1]['ThirdItem'] = [];
myObject.level1[0].ThirdItem[0] = {FirstItem: 'three', SecondItem: 'four'};
myObject.level1[1].ThirdItem[0] = {FirstItem: 'seven', SecondItem: 'eight'};
for (var i = 0; i < Object.keys(myObject.level1).length; i++) {
for (var j = 0; j < (Object.values(myObject.level1[i]).length); j++) {
if (typeof Object.values(myObject.level1[i])[j] === 'string') {
console.log(Object.values(myObject.level1[i])[j]);
}
else {
for (var k = 0; k < Object.values(myObject.level1[i])[j].length; k++) {
for (var l = 0; l < (Object.values(Object.values(myObject.level1[i])[j][k]).length); l++) {
if (typeof Object.values(Object.values(myObject.level1[i])[j][k])[l] === 'string') {
console.log(Object.values(Object.values(myObject.level1[i])[j][k])[l]);
}
}
}
}
}
}
Mais ... la boucle est absolument horrible. C'est verbeux et laid. Et, s'il était nécessaire d'aller encore plus loin dans l'objet, comment diable trouverait-il alors les itérateurs m
, n
, o
et p
?
Je suppose qu'un autre type de boucle (comme while
ou do... while
) pourrait être une meilleure approche, mais je ne vois pas comment javascript peut déterminer la profondeur de l'objet. En fin de compte, je spécule que c'est juste un exemple d'un modèle que je ne connais pas et j'utilise les mauvais outils, maladroitement, pour produire le bon résultat.
La réponse simple est "utiliser une fonction récursive" - ie. https://www.sitepoint.com/recursion-functional-javascript/ Chaque appel récursif recevra un objet/une collection différent (l'un des éléments enfants de l'objet "racine" de l'appel précédent/parent) sur lequel travailler. – user2864740