0

I'm trying to solve Length of missing array on CodeWars. This is my code.

function getLengthOfMissingArray(arr) {
  let result = 0;

  if (arr === null || arr.length === 0) return 0;

  arr = arr.sort((a, b) => b.length - a.length);
  console.log(arr)

  for (let i = 0; i < arr.length; i++) {

    if (arr[i].length === 0 || arr[i] === null) return 0;

    else if (arr[i].length - arr[i + 1].length !== 1) {
      console.log(arr[i].length);
      console.log(arr[i + 1].length);

      result = arr[i].length - 1;
    }
  }
  return result;
}


console.log(getLengthOfMissingArray([
  [5, 2, 9],
  [4, 5, 1, 1],
  [1],
  [5, 6, 7, 8, 9]
]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

The problem is that I keep getting the TypeError: Cannot read property 'length' of undefined. The console.log(arr[i + 1].length) worked and showing arr[i + 1].length is 1. I'm really confused with this. Can someone help me with this? Thank you!

TypeError: Cannot read property 'length' of undefined
    at getLengthOfMissingArray (/home/chrx/Documents/codeWars/Length of missing array.js:8:45)
    at Object.<anonymous> (/home/chrx/Documents/codeWars/Length of missing array.js:19:17)
    at Module._compile (internal/modules/cjs/loader.js:734:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:745:10)
    at Module.load (internal/modules/cjs/loader.js:626:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:566:12)
    at Function.Module._load (internal/modules/cjs/loader.js:558:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:797:12)
    at executeUserCode (internal/bootstrap/node.js:526:15)
    at startMainThreadExecution (internal/bootstrap/node.js:439:3)
4
  • 3
    Hint: what happens in the loop iteration when i is arr.length - 1? Commented Mar 9, 2019 at 4:58
  • Please give link to problem Commented Mar 9, 2019 at 4:59
  • @yiw qi what is your expected output in this case? Commented Mar 9, 2019 at 5:01
  • 1
    Consider [1,2,3]. The last index in the array is 2. When i = 2, i + 1 is 3. arr[3] is undefined. Commented Mar 9, 2019 at 5:02

4 Answers 4

1

Your main problem is an index overflow on the array at next line when performing the last iteration of the loop:

else if (arr[i].length - arr[i + 1].length !== 1)

Particularly when evaluating this code: arr[i + 1].length

However, I have made some extra fixes to your code, they are explained within the code:

function getLengthOfMissingArray(arr)
{
    // Check for all safe conditions at the start.

    if (!Array.isArray(arr) || arr.length === 0)
        return 0;

    if (arr.some(innerArr => !Array.isArray(innerArr)))
        return 0;

    // Sort mutates the array, there is no need to save it
    // again on arr variable.

    arr.sort((a, b) => b.length - a.length);

    // Start looping: to "arr.length - 1" maximum.

    for (let i = 0; i < arr.length - 1; i++)
    {
        // If find the missing length, return here, don't keep iterating.
        if (arr[i].length - arr[i + 1].length !== 1)
            return arr[i].length - 1;
    }
}

console.log("[Good Test] Missing length: ", getLengthOfMissingArray([
  [5, 2, 9],
  [4, 5, 1, 1],
  [1],
  [5, 6, 7, 8, 9]
]));

// Check samples with errors:

console.log("[Bad Test 1] Missing length: ", getLengthOfMissingArray(null));

console.log("[Bad Test 2] Missing length: ", getLengthOfMissingArray([]));

console.log("[Bad Test 3] Missing length: ", getLengthOfMissingArray([
  [5, 2, 9],
  "what?",
  [1],
  [5, 6, 7, 8, 9]
]));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

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

Comments

1

The reason it shows the error is because it overflows the array. Adding a check for arr[i + 1] should work.

if (!arr[i].length || !arr[i]|| !arr[i + 1]) return 0;

Comments

1

You loop upto the last element but you access next element (i+1) in the loop, which means it will overflow because there is no element after the last element, hence create an error of undefined.

If you intent to access next element (i+1) in the loop, you should only loop upto one element before the last element (arr.length - 1).

Here is the working code.

function getLengthOfMissingArray(arr) {
  let result = 0;

  if (arr === null || arr.length === 0) return 0;

  arr = arr.sort((a, b) => b.length - a.length);
  console.log(arr)

  // here is my only addition: loop upto a element before last element.
  for (let i = 0; i < arr.length-1; i++) {

    if (arr[i].length === 0 || arr[i] === null) return 0;

    else if (arr[i].length - arr[i + 1].length !== 1) {
      console.log(arr[i].length);
      console.log(arr[i + 1].length);

      result = arr[i].length - 1;
    }
  }
  return result;
}


console.log(getLengthOfMissingArray([
  [5, 2, 9],
  [4, 5, 1, 1],
  [1],
  [5, 6, 7, 8, 9]
]));

1 Comment

Thank you for the idea of arr.length - 1. I got it now.
1

When it will be the last iteration. i will be equal to arr.length - 1 and arr[i+1] will be undefined. You first check if arr[i+1] exists or not.

function getLengthOfMissingArray(arr) {
  let result = 0;
  if (arr === null || arr.length === 0) return 0;
  arr = arr.sort((a, b) => b.length - a.length);
  for (let i = 0; i < arr.length; i++) {
    if (arr[i].length === 0 || arr[i] === null) return 0;
    else if (arr[i+1] && arr[i].length - arr[i + 1].length !== 1) {
      result = arr[i].length - 1;
    }
  }
  return result;
}


console.log(getLengthOfMissingArray([
  [5, 2, 9],
  [4, 5, 1, 1],
  [1],
  [5, 6, 7, 8, 9]
]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

2 Comments

@yiwqi The code still give error. You need add this line arr = arr.filter(a => a !== null) before the sort() method to make the code pass all tests
In a test there is null inside array.so you need to remove it from otherwise it will give error when you will try to access .length of element in sort() method.

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.