yiw qi
yiw qi

Reputation: 73

Length of missing array using javascript

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)

Upvotes: 0

Views: 1739

Answers (4)

Shidersz
Shidersz

Reputation: 17190

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

Upvotes: 1

Maheer Ali
Maheer Ali

Reputation: 36594

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

Upvotes: 1

Gianfranco Fertino
Gianfranco Fertino

Reputation: 632

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

Upvotes: 1

Loc Mai
Loc Mai

Reputation: 217

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;

Upvotes: 1

Related Questions