Reputation: 73
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
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
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
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
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