0

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

6
  • Including the boundaries would be helpful if you could edit your question. Have you done any console.log() or general debugging to find out where it's going wrong instead of assuming/guessing? Commented Jun 1, 2019 at 16:26
  • Just edited, thanks. Commented Jun 1, 2019 at 16:27
  • What is the value of strarr and k when the function is called? Commented Jun 1, 2019 at 16:29
  • The final iteration of your for is i = 6. Your array has no item with an index of 6, so strarr[6] is undefined. Commented Jun 1, 2019 at 16:30
  • 1
    Also, while the purpose of the code isn't totally clear, I don't think your logic is correct. This code doesn't care how long the strings are - only that they are longer than the first string in the array. If you have two huge strings at the end of the array, it'll still just return abigailtheta. Commented Jun 1, 2019 at 16:32

4 Answers 4

1

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

Sign up to request clarification or add additional context in comments.

4 Comments

I think i should be start at 1.
This "fixes" OP's code, but for what it's worth, I don't think the code itself is doing what OP expects.
That was it, thanks so much, not sure how I didn't catch that!
@HyuckKang - Right, OP is comparing the first element of the array with the rest of them. Corrected.
0

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

Comments

0

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.

Comments

0

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:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.