semicolonjeff
semicolonjeff

Reputation: 1

Cannot read property 'length' of undefined error message in Javascript

I'm trying to solve a code challenge on code wars and don't understand why I'm getting an error message regarding the .length of a string inside of an array when I try to run it.

It's definitely the first .length in line 7. I've tried running other arr[i].lengths and they work, I'm thinking it's a problem with scope?

function longestConsec(strarr, k) {
  var arr = [];
  if (strarr.length == 0 || k > strarr.length || k <= 0) {
    return "";
  }
  for (var i = 1; i <= strarr.length; i++) {
    if (strarr[i].length > strarr[0].length && arr.length < k) {
      arr.push(strarr[i]);
    }
  }
  arr.join('');
}

longestConsec(["zone", "abigail", "theta", "form", "libe", "zas"], 2);

Should return "abigailtheta" as it's the 2 longest strings after the first string which were the requirements.

VM304:7 Uncaught TypeError: Cannot read property 'length' of undefined

Upvotes: 0

Views: 9523

Answers (4)

Meziane
Meziane

Reputation: 1667

You are iterating one time more than allowed:

for (var i = 1; i < strarr.length; i++) {
  if (strarr[i].length > strarr[0].length && arr.length < k) {
    arr.push(strarr[i]);
  }
}
arr.join('');
console.log(arr)

a working stackblitz:

Upvotes: 0

Tyler Roper
Tyler Roper

Reputation: 21672

As pointed out, you're iterating one time too many. Your final iteration will try to access an index that doesn't exist in your array.

That aside, your code doesn't seem to perform as you describe. It doesn't address the "longest" at any point, but rather just grabs the first two strings that are longer than the first.

If you wanted to find consecutive strings that combine for the longest length, consider something like this instead:

function longestConsec(strarr, k) {
  //invalid - exit
  if (strarr.length === 0 || k > strarr.length || k <= 0) return "";
  
  return strarr.reduce((out, str, idx, arr) => {
    if (idx+k > arr.length) arr.splice(1);          //exit early if at end of array
    
    let substring = arr.slice(idx,idx+k).join("");  //combine next k items into a string
    if (substring.length > out.length) {            //if it's the longest
      out.length = substring.length;                //save the length
      out.str = substring;                          //save the string
    }
    
    return out;
  }, {length: 0, str: ""});
}

var longest = longestConsec(["one", "seventeen", "four", "nineteen", "eleven", "five", "sixteen", "thirteen", "fourteen", "six"], 3);
console.log(longest);
.as-console-wrapper {max-height: none !important; top: 0;}

This has room for improvements regarding efficiency, as calling .slice() each time isn't exactly necessary, but in any case I believe the result is bit more in line with your task.

Upvotes: 0

David
David

Reputation: 7285

The elements in an array go from 0 to length - 1.

You have 6 strings in the array, the last one having the index 5.

Because the condition set that you should iterate while the index is lower or equal to strarr.length it tries to iterate the 6th element, which doesn't exist.

You should change the condition for the iteration:

for (var i = 1; i < strarr.length; i++) {

function longestConsec(strarr, k) {
  var arr = [];
  if (strarr.length == 0 || k > strarr.length || k <= 0) {
    return "";
  }
  for (var i = 1; i < strarr.length; i++) {
    if (strarr[i].length > strarr[0].length && arr.length < k) {
      arr.push(strarr[i]);
    }
  }
  arr.join('');
  alert(arr);
}

longestConsec(["zone", "abigail", "theta", "form", "libe", "zas"], 2);

Upvotes: 1

Rami Jarrar
Rami Jarrar

Reputation: 4643

You’re iterating on the array with the wrong boundaries .

You should change it to strarr.length - 1.

Or remove the less than or equal and use only less than operator

Because the index of the last accessible element in an array is the array length minus 1

Upvotes: 0

Related Questions