Undefined at the end of a while loop

Viewed 80

So this is my first time asking a question on stack overflow. My program is super simple and is just a practice that my friend is having me do to learn more about coding. Long story short here is my code:

let blocks = [
['H','L','S','J','U','B'],
['O','O','N','O','S','O'],
['M','V','O','Y','A','O'],
['E','E','W','' ,'' ,'' ]
];


let blocks_run = function(i,j) {
  while (i < blocks.length) {
    return blocks[i][j] + blocks_run(i+1,j)
  }
}

blocks_run(0,0);

for some reason, the response always returns undefined at the end.

e.g.

HOMEundefined

I just want to know why it's adding undefined to the end.

Thanks in advance!

8 Answers

let blocks = [
['H','L','S','J','U','B'],
['O','O','N','O','S','O'],
['M','V','O','Y','A','O'],
['E','E','W','' ,'' ,'' ]
];


let blocks_run = function(i,j) {
  while (i < blocks.length) {
    return blocks[i][j] + (blocks_run(i+1,j) ?? '');
  }
}

console.log(blocks_run(0,0));

Another possible solution.

let blocks_run = function(i,j) {
  while (i < blocks.length) {
    return blocks[i][j] + blocks_run(i+1,j)
  }
}

This function uses while instead of if to execute a return statement which recursively calls the function. If the condition fails because i is out of bounds, it doesn't explicitly return anything, which in JavaScript means the function returns undefined.

Depending on what you want, you could try

let blocks_run = function(i,j) {
  if (i < blocks.length) {
    return blocks[i][j] + blocks_run(i+1,j)
  }
  return ""; // not undefined
}

There's no need for a loop since it'll never run more than one iteration. The conditional operator will allow you to put the whole function body into a single expression.

let blocks = [
['H','L','S','J','U','B'],
['O','O','N','O','S','O'],
['M','V','O','Y','A','O'],
['E','E','W','' ,'' ,'' ]
];


const blocks_run = (i, j) => 
  i < blocks.length ? blocks[i][j] + blocks_run(i+1,j) : '';

console.log(blocks_run(0,0));

let blocks = [
['H','L','S','J','U','B'],
['O','O','N','O','S','O'],
['M','V','O','Y','A','O'],
['E','E','W','' ,'' ,'' ]
];


let blocks_run = function(i,j) {
  while (i < blocks.length) {
    return blocks[i][j] + blocks_run(i+1,j)
  }
  return '';
}

console.log(blocks_run(0,0));

Your recursion function by default is returning undefined

On the last row, you're still retrieving the next row, which is undefined.

Recursive functions need to have a "base case" that tells them to stop recursing.

let blocks = [
  ['H', 'L', 'S', 'J', 'U', 'B'],
  ['O', 'O', 'N', 'O', 'S', 'O'],
  ['M', 'V', 'O', 'Y', 'A', 'O'],
  ['E', 'E', 'W',  '',  '',  '']
];


let blocks_run = function(row, col) {
  while (row < blocks.length) {
    return row + 1 < blocks.length 
      ? blocks[row][col] + blocks_run(row + 1, col)
      : blocks[row][col];
  }
}
console.log(blocks_run(0, 0));

You need to return something in the event that i >= blocks.length, for example:

  while (i < blocks.length) {
    return blocks[i][j] + blocks_run(i+1,j)
  }
  return '';

Refactored for readability

let blocks_run = function(i,j) {
  /* base case */
  if (i == blocks.length) {
    return '';
  }

  return blocks[i][j] + blocks_run(i+1,j);
}

You see, this is how recursion works; blocks_run needs to return something, so when the recursion terminates and you haven't specified a base case, you get the return value of undefined. Since the function that called blocks_run the last time was indeed the same function, the while condition terminated and you ended up with + undefined.

For the last iteration while loop inside your method won't run as i value would be equal to blocks.length. As your method is returning nothing when while condition becomes false. It means it is returning undefined by default. That's what is concatenated in the last. So return empty string to resolve this issue.

Solution:

let blocks = [
['H','L','S','J','U','B'],
['O','O','N','O','S','O'],
['M','V','O','Y','A','O'],
['E','E','W','' ,'' ,'' ]
];


let blocks_run = function(i,j) {
  while (i < blocks.length) {
    return blocks[i][j] + blocks_run(i+1,j)
  }
  return ''
}

blocks_run(0,0);
Related