Seuta K
Seuta K

Reputation: 107

Comparison operator is not working on 0 in JavaScript

I've been trying to answer this question which I stumbled upon Codewars.

You are given an array (which will have a length of at least 3 but could be very large) containing integers. The array is either entirely comprised of odd integers or entirely comprised of even integers except for a single integer N. Write a method that takes the array as an argument and returns this "outlier" N.

and here is my initial answer.

let array = [0, 1, 2];

function findOutlier(integers) {
  let evens = integers.filter(item => {
    if (item % 2 === 0 || item === 0) {
      return item;
    }
  });
  let odds = integers.filter(item => {
    if (item % 2 !== 0) {
      return item;
    }
  });
  if (evens.length > 1) {
    return odds[0];
  } else {
    return evens[0];
  }
}
console.log(findOutlier(array));

But apparently item === 0 is not working in the code above, and it returns [2] as the value of evens (missing out 0). Then I changed the code like below and it works!

let array = [0, 1, 2];

function findOutlier(integers) {
  let evens = integers.filter(item => {
    if (item = 0 || item % 2 === 0) {
      return item;
    }
  });
  let odds = integers.filter(item => {
    if (item % 2 !== 0) {
      return item;
    }
  });
  if (evens.length > 1) {
    return odds[0];
  } else {
    return evens[0];
  }
}
console.log(findOutlier(array));

I'm still pretty confused about why the comparison operator didn't work in the first code. Much appreciated it if you could help me understand..!

Upvotes: 0

Views: 967

Answers (3)

Nguyễn Văn Phong
Nguyễn Văn Phong

Reputation: 14228

The problem is here

let evens = integers.filter(item => {
    if (item = 0 || item % 2 === 0) {
      return item; // You are return value instead of boolean
    }
});

It should be

let evens = integers.filter(item => {
    return item == 0 || item % 2 == 0; // It should be returned boolean
});

Simply because according to MDN's filter method say that:

callback function is a predicate, to test each element of the array. Return a value that coerces to true to keep the element, or to false otherwise`.

let array = [0, 1, 2];

function findOutlier(integers){
    let evens = integers.filter(item => {
        return item == 0 || item % 2 == 0;
    });
    let odds = integers.filter(item => {
        return item % 2 !== 0;
    });
    
    if(evens.length > 1) {
        return odds[0];
    } else {
        return evens[0];
    }
}
console.log(findOutlier(array));

Optimize performance

function findOutlier(integers){
   const result = integers.reduce((acc, curr) => {
      if(curr % 2 === 0)
        acc["evens"].push(curr);
      else
        acc["odds"].push(curr);
      return acc;
    }, { evens: [],  odds: []});
    
   return result["evens"].length > 1 ? result["odds"][0] : result["evens"][0];
}
console.log(findOutlier([0, 1, 2]));

Upvotes: 1

DecPK
DecPK

Reputation: 25401

In the filter method you need to return true or false and you are returning the value. And in the first case 0 will get returned as per your code and 0 is considered as a falsy value. so It won't show in the final result.

let array = [0, 1, 2];

function findOutlier(integers) {
  let evens = integers.filter((item) => {
    if (item % 2 === 0) {
      return true;
    }
    return false;
  });

  console.log(evens);

  let odds = integers.filter((item) => {
    if (item % 2 !== 0) {
      return true;
    }
    return false;
  });

  console.log(odds);

  if (evens.length > 1) {
    return odds[0];
  } else {
    return evens[0];
  }
}
console.log(findOutlier(array));

You can make this code more readable as shown in below snippet

let array = [0, 1, 2];

function findOutlier(integers) {
  let evens = integers.filter(item => item % 2 === 0);
  let odds  = integers.filter(item => item % 2 !== 0);

  if (evens.length > 1) return odds[0];
  else return evens[0];
}

console.log(findOutlier(array));

Upvotes: 1

mymedia
mymedia

Reputation: 617

The .filter() method receives a predicate that must return boolean value, true or false, not item. That's first mistake. The second one is using assignment = inside if condition. Single equal sign does not mean comparison.

To fix this, you can replace return item with return true within your first code sample. However, I would recommend you to use a simple loop.

function findOutlier(integers) {
  for (let item of integers) {
    if (item % 2 != 0) {
      return item;
    }
  }
  return integers[0];
}

Upvotes: 1

Related Questions