Loop until find an array empty in Javascript

Viewed 117

I'm trying to find a solution to make a loop (Javascript) until the array of object is empty. Here the object that I want to use :

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

I would like to loop until to find the variable evolves_to empty. and in each loop using the species.name, to list the evolution, in my case : nidoran-f -> nidorina -> nidoqueen

I can not find yet a good way to do it. A bit lost. Thank you for your help ;)

2 Answers

You can use a recursive function:

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)

Or to collect values in an 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(" -> "))

A simple recursive function should do the trick:

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);

The result evolution array is then reversed to begin from the 1st evolution via reverse() and joined by arrows via joing(' -> ').

Related