Home > Back-end >  Why reduce() is returning NaN when multiplying big array
Why reduce() is returning NaN when multiplying big array

Time:01-28

I'm solving a problem 1822 from leetcode and I'm stuck with reduce() returning NaN.

There is a function signFunc(x) that returns:

1 if x is positive. -1 if x is negative. 0 if x is equal to 0. You are given an integer array nums. Let product be the product of all values in the array nums.

Return signFunc(product).

My try of solution:

var arraySign = function(nums) {return Math.sign(nums.reduce((acc, curr) => acc * curr));};

console.log(arraySign([1,5,0,2,-3]));

When I pass simple array like [1,5,0,2,-3] everything is okay, but when I pass monster like

[1,28,-91,-62,-36,-1,-84,-90,-92,61,6,-58,-60,2,51,-15,-18,-81,87,84,100,-84,-13,-87,-33,72,-72,-59,-79,28,-69,-97,-93,17,67,11,-12,19,5,42,-85,71,-77,-82,26,-58,-51,-14,63,-85,-86,66,47,57,-86,-25,-75,59,-17,-71,89,-78,-42,30,39,61,-96,-30,-29,-92,-90,69,20,65,32,92,44,-71,-18,87,-86,23,-96,-21,-49,-96,-98,35,-11,-1,81,-48,68,5,75,57,-30,-7,32,86,-29,-86,-61,45,-31,-93,-26,-9,86,57,-52,75,68,-58,14,27,-94,47,-38,-44,75,-83,21,-83,43,62,74,97,78,43,54,28,64,-19,-89,88,68,18,-96,-83,-25,-71,88,-84,-24,-61,72,-90,-56,29,46,56,51,16,66,-2,65,-95,16,51,42,61,99,89,-93,59,-99,69,26,-61,21,41,40,-4,-49,3,-96,57,65,72,-41,-77,-4,61,71,-88,21,-95,38,64,92,0,-63]

var arraySign = function(nums) {return Math.sign(nums.reduce((acc, curr) => acc * curr));};

console.log(arraySign([1,28,-91,-62,-36,-1,-84,-90,-92,61,6,-58,-60,2,51,-15,-18,-81,87,84,100,-84,-13,-87,-33,72,-72,-59,-79,28,-69,-97,-93,17,67,11,-12,19,5,42,-85,71,-77,-82,26,-58,-51,-14,63,-85,-86,66,47,57,-86,-25,-75,59,-17,-71,89,-78,-42,30,39,61,-96,-30,-29,-92,-90,69,20,65,32,92,44,-71,-18,87,-86,23,-96,-21,-49,-96,-98,35,-11,-1,81,-48,68,5,75,57,-30,-7,32,86,-29,-86,-61,45,-31,-93,-26,-9,86,57,-52,75,68,-58,14,27,-94,47,-38,-44,75,-83,21,-83,43,62,74,97,78,43,54,28,64,-19,-89,88,68,18,-96,-83,-25,-71,88,-84,-24,-61,72,-90,-56,29,46,56,51,16,66,-2,65,-95,16,51,42,61,99,89,-93,59,-99,69,26,-61,21,41,40,-4,-49,3,-96,57,65,72,-41,-77,-4,61,71,-88,21,-95,38,64,92,0,-63]));
I got only "NaN" return. At this moment I skipped this bug by if's:

var arraySign = function(nums) {
let product = nums.reduce((acc, curr) => acc * curr);

if(product>0) return 1;
else if (product<0) return -1;
else return 0;};

But i want to know: why reduce is not working in this problem? Is there any limit for reduce()?

CodePudding user response:

The problem is not with reduce. The problem is that you're multiplying a lot of numbers, which amounts to Infinity (or -Infinity), and then you're also multiplying that by 0. But Infinity * 0 gives NaN.

You can solve this by only multiplying the signs of the numbers:

function arraySign(nums) {
  return nums.reduce((acc, curr) => acc * Math.sign(curr), 1);
};

CodePudding user response:

Off Topic: But you can solve this by simply counting the number of negative values and looking for zeroes.

Every 2 negative values, the signs will cancel each other out and the result becomes positive.

  • an even number of negative values will have a positive result
  • an odd number of negative values will have a negative result
  • and the positive values in the list have no influence whatsoever on the sign of the result.

const arraySign = function(nums) {
  // if the array contains a `0` the result will be `0`.
  // 0 * whatever will always stay 0
  if (nums.includes(0)) return 0;

  let count = 0;
  for (const value of nums) count  = value < 0;

  return count & 1 ? -1 : 1;
}

const nums = [1, 28, -91, -62, -36, -1, -84, -90, -92, 61, 6, -58, -60, 2, 51, -15, -18, -81, 87, 84, 100, -84, -13, -87, -33, 72, -72, -59, -79, 28, -69, -97, -93, 17, 67, 11, -12, 19, 5, 42, -85, 71, -77, -82, 26, -58, -51, -14, 63, -85, -86, 66, 47, 57, -86, -25, -75, 59, -17, -71, 89, -78, -42, 30, 39, 61, -96, -30, -29, -92, -90, 69, 20, 65, 32, 92, 44, -71, -18, 87, -86, 23, -96, -21, -49, -96, -98, 35, -11, -1, 81, -48, 68, 5, 75, 57, -30, -7, 32, 86, -29, -86, -61, 45, -31, -93, -26, -9, 86, 57, -52, 75, 68, -58, 14, 27, -94, 47, -38, -44, 75, -83, 21, -83, 43, 62, 74, 97, 78, 43, 54, 28, 64, -19, -89, 88, 68, 18, -96, -83, -25, -71, 88, -84, -24, -61, 72, -90, -56, 29, 46, 56, 51, 16, 66, -2, 65, -95, 16, 51, 42, 61, 99, 89, -93, 59, -99, 69, 26, -61, 21, 41, 40, -4, -49, 3, -96, 57, 65, 72, -41, -77, -4, 61, 71, -88, 21, -95, 38, 64, 92, 0, -63];

console.log(arraySign([1,5,2,-3]));
console.log(arraySign(nums));

  • Related