简体   繁体   中英

Recursion function yielding infinite loop in Javascript

I'm having some major problems using recursion functions to generate a simple table. My goal is to generate a table in HTML that outputs a different row for each possible combination of elements in my sub arrays:

var paras = [
 [1, 2, 3],
 ["a", "b", "c"],
 //[7, 8, 9], //WARNING!!! UNCOMMENTING THIS LINE WILL RESULT IN AN INFINITE LOOP
 //['1/8"', '3/16"', '1/4"'],
 //['6"', '12"', '18"'],
 //["316SS"],
 //["Grounded", "Ungrounded", "Exposed"],
];

For example, in the above array I would like to generate something along the lines of:

1a7
1a8
1a9
1b7
1b8
1b9
1c7...
3c9

Eventually I'd like that to be output into a table in HTML but for now all I care about is basically getting that pattern generated anyway that I can.

Now for the hard part. I can't use nested for loops. It would be easy to have 3 loops nested in each other each going from 1 to the length of the particular subarray, but what about when i have 4 subarrays, or 10, or 1000. I'd like the code to be independent of how many subarrays, and how many variables in each sub array, there are.

var numcats = paras.length;
var retStack = [];
var retQ = [];



function genTable(array1) {
  if (array1.length == 1) { //if there is only 1 sub-array (base case)
    if (array1[0].length == 1) { //if that array contains only 1 element
      retStack.push(array1[0][0]);
      return retStack;
    } else {
      var temp = array1;
      var item = temp[0].pop();
      retStack = genTable(temp);
      retStack.push(item);
      return retStack; //returns 1 2 3 when there is only 1 sub array
    }
  } else {
    var tempParas = array1;
    var topArray = tempParas.pop();
    var permQ = genTable(tempParas);
    for (i = 0; i < topArray.length; i++) {
      var tempQ = [];
      var tempQ = permQ;
      while (tempQ.length >= 1) {
        retQ.push(topArray[i]);
        for (j = 0; j < tempParas.length; j++) {
          retQ.push(tempQ.pop());
        }
      }
    }
    return retQ; //returns a 3 a 2 a 1 when there are 2 sub-arrays
  }
}

console.log(genTable(paras))

My problems:

  • When i have 2 subarrays (as shown above) the return is a 3 a 2 a 1. I might be able to fix the reverse order problem by using shift instead of pop? But why does it not go on to b and c.
  • When i have 3 or more subarrays I get trapped in an infinite loop (i believe the while loop isn't breaking because the variable in the condition isn't defining correctly? maybe..?

Here is my jsfiddle if you want to see my actual code (pretty much the same but messier as it has lots of console.logs to help me debug) - http://jsfiddle.net/wmkNe/206/

What you are trying to do is Array Recursion. This will iterate through all of the arrays in your paras variable.

I have updated your fiddle

var paras = [
  [1, 2, 3],
 ["a", "b", "c"],
 [7, 8, 9], //WARNING!!! UNCOMMENTING THIS LINE WILL RESULT IN AN INFINITE LOOP
 ['1/8"', '3/16"', '1/4"'],
 ['6"', '12"', '18"'],
 ["316SS"],
 ["Grounded", "Ungrounded", "Exposed"],
];

function arrayRecursion(paras) {
  if (paras.length == 1) 
    return paras[0];

  var results = [];
  var allValues = arrayRecursion(paras.slice(1));
  for (var i = 0; i < allValues.length; i++) {
    for (var j = 0; j < paras[0].length; j++) {
      results.push(paras[0][j] + allValues[i]);
    }
  }
  return results;    
}

console.log(arrayRecursion(paras));

This returns results as: ["1a71/8"6"316SSGrounded", "2a71/8"6"316SSGrounded", "3a71/8"6"316SSGrounded", "1b71/8"6"316SSGrounded", "2b71/8"6"316SSGrounded",...]

Looking at this I'm thinking this is like counting in a base system using different base and symbols per position:

function getCounter(arrSymbols) {
  const arrSymbolsReversed = arrSymbols.reverse();
  return n => arrSymbolsReversed
    .reduce((o, s) => ({str:  s[o.n % s.length]+o.str, n: Math.floor(o.n / s.length)}), {str:"",n:n})
    .str;
}
var count = getCounter([['1','2','3'],['a','b','c'],['7','8','9']]);
_.range(0,27).map(count); //=> ["1a7", "1a8", ...]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM