json - Loopa tills du hittar en tom array i Javascript


Jag försöker hitta en lösning för att göra en loop (Javascript) tills arrayen av objekt är tom. Här är objektet som jag vill använda:

"chain": {
    "evolves_to": [{
        "evolves_to": [{
            "evolves_to": [],
            "species": {
                "name": "nidoqueen"
            }
        }],
        "species": {
            "name": "nidorina"
        }
    }],
    "species": {
        "name": "nidoran-f"
    }
}

Jag skulle vilja loopa tills variabeln evolves_to är tom. Och i varje loop använda species.name för att lista evolutionen, i mitt fall: nidoran-f -> nidorina -> nidoqueen

Jag kan fortfarande inte hitta ett bra sätt att göra det. Lite vilse. Tack för din hjälp ;)

Svar #1

Du kan använda en rekursiv funktion:

const chain = {
    "evolves_to": [{
        "evolves_to": [{
            "evolves_to": [],
            "species": {
                "name": "nidoqueen"
            }
        }],
        "species": {
            "name": "nidorina"
        }
    }],
    "species": {
        "name": "nidoran-f"
    }
}
, traverse = obj => {
  if(!obj.evolves_to.length) {
    console.log(obj.species.name)
    return
  } else {
    console.log(obj.species.name, "=>")
    traverse(obj.evolves_to[0])    
  }
}

traverse(chain)

Eller att samla värden i en array:

const chain = {
    "evolves_to": [{
        "evolves_to": [{
            "evolves_to": [],
            "species": {
                "name": "nidoqueen"
            }
        }],
        "species": {
            "name": "nidorina"
        }
    }],
    "species": {
        "name": "nidoran-f"
    }
}
, arr = []
, traverse = obj => {
  if(!obj.evolves_to.length) {
    arr.push(obj.species.name)
    return
  } else {
    arr.push(obj.species.name)
    traverse(obj.evolves_to[0])    
  }
}

traverse(chain)
console.log(arr.join(" -> "))

Svar #2

En enkel rekursiv funktion borde göra susen:

const evolutions = { 
  "chain": {
    "evolves_to": [{
        "evolves_to": [{
            "evolves_to": [],
            "species": {
                "name": "nidoqueen"
            }
        }],
        "species": {
            "name": "nidorina"
        }
    }],
    "species": {
        "name": "nidoran-f"
    }
  }
}

function findNoEvolution(obj, evolutionStages) {
  if (obj.evolves_to.length > 0) {
    for (let i = 0; i < obj.evolves_to.length; i += 1) {
      const found = findNoEvolution(obj.evolves_to[i], evolutionStages);
      if (found) {
        evolutionStages.push(obj.species.name)
        return found;
      }
    }
  }
  evolutionStages.push(obj.species.name)
  return true;
}

const evolutionStages = [];
findNoEvolution(evolutions.chain, evolutionStages);
const evolutionStagesStr = evolutionStages.reverse().join(' -> ');
console.log(evolutionStagesStr);

Resultatet av evolutionsarrayen vänds sedan för att börja från den första evolutionen via reverse() och förenas med pilar via joing(' -> ').