Home > Software design >  javascript recursive function giving error
javascript recursive function giving error

Time:09-24

I have my JSON structured like below which has the next and previous properties of an array of keys from the same structure.

{
  "e6e1de44-d53b-44ae-9d52-8f6e1358f8ec": {
    "course": "Semester 1",
    "status": "completed",
    "next": [
      "d1fc647b-ad7e-4b72-9269-5559948ee61d"
    ],
    "previous": [],
  },
  "d1fc647b-ad7e-4b72-9269-5559948ee61d": {
    "course": "Semester 2",
    "status": "completed",
    "next": [
      "cb00b200-cee3-4ab8-af11-abb7ea26183b",
      "7b958370-d697-4536-9bff-fa564a5688ef"
    ],
    "previous": [
      "e6e1de44-d53b-44ae-9d52-8f6e1358f8ec"
    ],
  },
  "cb00b200-cee3-4ab8-af11-abb7ea26183b": {
    "course": "Semester 3",
    "status": "active",
    "next": [
      "72488692-064c-436c-93cb-8ebe2be7e168"
    ],
    "previous": [
      "d1fc647b-ad7e-4b72-9269-5559948ee61d"
    ],
  },
  "7b958370-d697-4536-9bff-fa564a5688ef": {
    "course": "Semester 4",
    "status": "active",
    "next": [
      "72488692-064c-436c-93cb-8ebe2be7e168"
    ],
    "previous": [
      "d1fc647b-ad7e-4b72-9269-5559948ee61d"
    ],
  },
  "72488692-064c-436c-93cb-8ebe2be7e168": {
    "course": "Final",
    "status": "not-started",
    "next": [],
    "previous": [
      "cb00b200-cee3-4ab8-af11-abb7ea26183b",
      "7b958370-d697-4536-9bff-fa564a5688ef"
    ],
  }
}

I am trying to get the next array and the previous array recursively but it is giving me an error TypeError: Cannot read properties of undefined (reading 'recursiveFunc') I'm calling a function like this.

let nextRes = [];
recursiveFunc(courseData, 'e6e1de44-d53b-44ae-9d52-8f6e1358f8ec', nextRes, true);
let prevRes = [];
recursiveFunc(courseData, 'cb00b200-cee3-4ab8-af11-abb7ea26183b', prevRes, false);

I was wondering if the same function could be used to achieve a similar result. It is just a matter of traversing forward or backward. How can I get the id of the next data recursively? nextRes shuld have populated ['d1fc647b-ad7e-4b72-9269-5559948ee61d', 'cb00b200-cee3-4ab8-af11-abb7ea26183b', '7b958370-d697-4536-9bff-fa564a5688ef', '72488692-064c-436c-93cb-8ebe2be7e168'] and prevRes like ['d1fc647b-ad7e-4b72-9269-5559948ee61d', 'e6e1de44-d53b-44ae-9d52-8f6e1358f8ec']

function recursiveFunc(data, parId, acc, forward) {
  for (let property in data) {
    if (data.hasOwnProperty(property) && typeof data[property] === 'object') {

      var current = data[property];

      if (forward && property == parId && typeof current.preReqStages === 'object' && data[property].next.length > 0) {
        acc.push(current.next);
      } else if (!forward && property == parId && typeof current.preReqStages === 'object' && data[property].previous.length > 0) {
        acc.push(current.previous);
      } else {
        this.recursiveFunc(data, property, acc, forward)
      }
    }
  }
}

CodePudding user response:

Starting in order of your code, first you don't need to validate data.hasOwnProperty(property) if you're making a for of the properties in data.

Second, your validation of typeof current.preReqStages === 'object' should be typeof current.next === 'object' or current.previous for the next if, since you don't have a value of preReqStages.

Then, you are adding current.next to your array, meaning you're adding an array inside an array, when you only want the value, so I added a forEach and added each value.

And then the recursion should be inside the matches, because what you want to get is all the chain of courses, meaning that when you get the next one, you need to get the next one of that new property. So I made the recursion inside the forEach.

Here's the final result:

const courseData = {
  "e6e1de44-d53b-44ae-9d52-8f6e1358f8ec": {
    "course": "Semester 1",
    "status": "completed",
    "next": [
      "d1fc647b-ad7e-4b72-9269-5559948ee61d"
    ],
    "previous": [],
  },
  "d1fc647b-ad7e-4b72-9269-5559948ee61d": {
    "course": "Semester 2",
    "status": "completed",
    "next": [
      "cb00b200-cee3-4ab8-af11-abb7ea26183b",
      "7b958370-d697-4536-9bff-fa564a5688ef"
    ],
    "previous": [
      "e6e1de44-d53b-44ae-9d52-8f6e1358f8ec"
    ],
  },
  "cb00b200-cee3-4ab8-af11-abb7ea26183b": {
    "course": "Semester 3",
    "status": "active",
    "next": [
      "72488692-064c-436c-93cb-8ebe2be7e168"
    ],
    "previous": [
      "d1fc647b-ad7e-4b72-9269-5559948ee61d"
    ],
  },
  "7b958370-d697-4536-9bff-fa564a5688ef": {
    "course": "Semester 4",
    "status": "active",
    "next": [
      "72488692-064c-436c-93cb-8ebe2be7e168"
    ],
    "previous": [
      "d1fc647b-ad7e-4b72-9269-5559948ee61d"
    ],
  },
  "72488692-064c-436c-93cb-8ebe2be7e168": {
    "course": "Final",
    "status": "not-started",
    "next": [],
    "previous": [
      "cb00b200-cee3-4ab8-af11-abb7ea26183b",
      "7b958370-d697-4536-9bff-fa564a5688ef"
    ],
  }
}


function recursiveFunc(data, parId, acc, forward) {
  for (let property in data) {
    if (typeof data[property] === 'object') {
      var current = data[property];

      if (forward && property == parId && typeof current.next === 'object' && current.next.length > 0) {
        current.next.forEach(n => {
          if (!acc.includes(n)) {
            acc.push(n)
            this.recursiveFunc(data, n, acc, forward)
          }
        });
      } else if (!forward && property == parId && typeof current.previous === 'object' && current.previous.length > 0) {
        current.previous.forEach(p => {
          if (!acc.includes(p)) {
            acc.push(p)
            this.recursiveFunc(data, p, acc, forward)
          }
        });
      }
    }
  }
}


let nextRes = [];
recursiveFunc(courseData, 'e6e1de44-d53b-44ae-9d52-8f6e1358f8ec', nextRes, true);
console.log(nextRes)
let prevRes = [];
recursiveFunc(courseData, 'cb00b200-cee3-4ab8-af11-abb7ea26183b', prevRes, false);
console.log(prevRes)

  • Related