admin管理员组

文章数量:1022670

I'm doing this challenge on codewars, it passed all the test but I got an error:

TypeError: Cannot read property 'length' of null

so I can't past the challenge. Can anyone tell me what's wrong with this code ?

function averages(numbers) {
  for(var i=0; i<numbers.length; i++){
    if(numbers.length < 2 || numbers[i] === ""){
      return [];
    } else {
      numbers[i] = (numbers[i] + numbers[i+1]) / 2;
    }
  }
  numbers.pop();
  return numbers
}

I'm doing this challenge on codewars, it passed all the test but I got an error:

TypeError: Cannot read property 'length' of null

so I can't past the challenge. Can anyone tell me what's wrong with this code ?

function averages(numbers) {
  for(var i=0; i<numbers.length; i++){
    if(numbers.length < 2 || numbers[i] === ""){
      return [];
    } else {
      numbers[i] = (numbers[i] + numbers[i+1]) / 2;
    }
  }
  numbers.pop();
  return numbers
}
Share Improve this question edited Feb 21, 2017 at 21:04 halfer 20.4k19 gold badges109 silver badges202 bronze badges asked Feb 10, 2017 at 12:54 MikeMike 1033 gold badges4 silver badges11 bronze badges 2
  • well, what do you expect length to be if null is passed as parameter? – UnholySheep Commented Feb 10, 2017 at 12:55
  • you're passing numbers to your function, wich should be an array, if not, it will show that error. So be carefull about always passing an array, even if it's only 1 number. – LordNeo Commented Feb 10, 2017 at 12:58
Add a ment  | 

4 Answers 4

Reset to default 3

There is an important part of the instructions that you aren't handling:

If the array has 0 or 1 values or is null or None, your method should return an empty array.

function averages(numbers) {
  if (!numbers) return []; // return empty array

  for(var i=0; i<numbers.length; i++){
    if(numbers.length < 2 || numbers[i] === ""){
      return [];
    } else {
      numbers[i] = (numbers[i] + numbers[i+1]) / 2;
    }
  }
  numbers.pop();
  return numbers
}

You just need to test if the parameter is null

  //test if numbers is null
  if(numbers == null){
    return [];
  }
  for(var i=0; i<numbers.length; i++){
    if(numbers.length < 2 || numbers[i] === ""){
      return [];
    } else {
      numbers[i] = (numbers[i] + numbers[i+1]) / 2;
    }
  }
  numbers.pop();
  return numbers
function averages(numbers) {
  if(numbers)
  {
    for(var i=0; i<numbers.length; i++){
      if(numbers.length < 2 || numbers[i] === ""){
        return [];
      } else {
        numbers[i] = (numbers[i] + numbers[i+1]) / 2;
      }
    }
    numbers.pop();
    return numbers
  }
  else
  {
    return [];
  }

}

Just add a null check to ur numbers variable. Then you are good to go.

To correct your code:

function averages(numbers) {
  if (!Array.isArray(numbers)) {
    return [];
  }
  for(var i=0; i<numbers.length; i++){
    if(numbers.length < 2){
      return [];
    } else {
      numbers[i] = (numbers[i] + numbers[i+1]) / 2;
    }
  }
  numbers.pop();
  return numbers
}

I use Array.isArray to check that it is really an array. It is an inbuilt function, so you should use it.

You can check this and the length in one step, saving more steps (look the example below).

To provide a cleaner solution:

function averages(numbers) {
  if (!Array.isArray(numbers) || numbers.length < 2) {
    return [];
  }
  for(var i = 0; i < numbers.length - 1; i++){
      numbers[i] = (numbers[i] + numbers[i + 1]) / 2;
  }
  numbers.pop();
  return numbers
}

It works fine, I also added a "-1" to the loop, as the last number will bee "NaN" (Not a Number), because there is no element after it and (10 + undefined) / 2 => NaN / 2 => NaN. This also adds an unnecessary step to your algorithm.

To make it plete

Another solution might be Array:map:

function averages(numbers) {
  if (!Array.isArray(numbers) || numbers.length < 2) {
    return [];
  }
  numbers.map(function(val, idx, arr) {
    arr[idx] = (val + arr[idx+1]) / 2;
  });
  numbers.pop();
  return numbers;
}

I'm doing this challenge on codewars, it passed all the test but I got an error:

TypeError: Cannot read property 'length' of null

so I can't past the challenge. Can anyone tell me what's wrong with this code ?

function averages(numbers) {
  for(var i=0; i<numbers.length; i++){
    if(numbers.length < 2 || numbers[i] === ""){
      return [];
    } else {
      numbers[i] = (numbers[i] + numbers[i+1]) / 2;
    }
  }
  numbers.pop();
  return numbers
}

I'm doing this challenge on codewars, it passed all the test but I got an error:

TypeError: Cannot read property 'length' of null

so I can't past the challenge. Can anyone tell me what's wrong with this code ?

function averages(numbers) {
  for(var i=0; i<numbers.length; i++){
    if(numbers.length < 2 || numbers[i] === ""){
      return [];
    } else {
      numbers[i] = (numbers[i] + numbers[i+1]) / 2;
    }
  }
  numbers.pop();
  return numbers
}
Share Improve this question edited Feb 21, 2017 at 21:04 halfer 20.4k19 gold badges109 silver badges202 bronze badges asked Feb 10, 2017 at 12:54 MikeMike 1033 gold badges4 silver badges11 bronze badges 2
  • well, what do you expect length to be if null is passed as parameter? – UnholySheep Commented Feb 10, 2017 at 12:55
  • you're passing numbers to your function, wich should be an array, if not, it will show that error. So be carefull about always passing an array, even if it's only 1 number. – LordNeo Commented Feb 10, 2017 at 12:58
Add a ment  | 

4 Answers 4

Reset to default 3

There is an important part of the instructions that you aren't handling:

If the array has 0 or 1 values or is null or None, your method should return an empty array.

function averages(numbers) {
  if (!numbers) return []; // return empty array

  for(var i=0; i<numbers.length; i++){
    if(numbers.length < 2 || numbers[i] === ""){
      return [];
    } else {
      numbers[i] = (numbers[i] + numbers[i+1]) / 2;
    }
  }
  numbers.pop();
  return numbers
}

You just need to test if the parameter is null

  //test if numbers is null
  if(numbers == null){
    return [];
  }
  for(var i=0; i<numbers.length; i++){
    if(numbers.length < 2 || numbers[i] === ""){
      return [];
    } else {
      numbers[i] = (numbers[i] + numbers[i+1]) / 2;
    }
  }
  numbers.pop();
  return numbers
function averages(numbers) {
  if(numbers)
  {
    for(var i=0; i<numbers.length; i++){
      if(numbers.length < 2 || numbers[i] === ""){
        return [];
      } else {
        numbers[i] = (numbers[i] + numbers[i+1]) / 2;
      }
    }
    numbers.pop();
    return numbers
  }
  else
  {
    return [];
  }

}

Just add a null check to ur numbers variable. Then you are good to go.

To correct your code:

function averages(numbers) {
  if (!Array.isArray(numbers)) {
    return [];
  }
  for(var i=0; i<numbers.length; i++){
    if(numbers.length < 2){
      return [];
    } else {
      numbers[i] = (numbers[i] + numbers[i+1]) / 2;
    }
  }
  numbers.pop();
  return numbers
}

I use Array.isArray to check that it is really an array. It is an inbuilt function, so you should use it.

You can check this and the length in one step, saving more steps (look the example below).

To provide a cleaner solution:

function averages(numbers) {
  if (!Array.isArray(numbers) || numbers.length < 2) {
    return [];
  }
  for(var i = 0; i < numbers.length - 1; i++){
      numbers[i] = (numbers[i] + numbers[i + 1]) / 2;
  }
  numbers.pop();
  return numbers
}

It works fine, I also added a "-1" to the loop, as the last number will bee "NaN" (Not a Number), because there is no element after it and (10 + undefined) / 2 => NaN / 2 => NaN. This also adds an unnecessary step to your algorithm.

To make it plete

Another solution might be Array:map:

function averages(numbers) {
  if (!Array.isArray(numbers) || numbers.length < 2) {
    return [];
  }
  numbers.map(function(val, idx, arr) {
    arr[idx] = (val + arr[idx+1]) / 2;
  });
  numbers.pop();
  return numbers;
}

本文标签: Cannot read property 39length39 of null in JavaScriptStack Overflow