0

I looked some time but to my surprise haven't found any answer to specifically this.

I would like to check if values have changed in our data set tool. For this i would like to use loose comparison so that equivalent numbers converted to string (just an example) are not detected changed:

42 != "42" // -> false

However, for obvious reasons, i would like that falsey comparisons are compared strictly, except when they are equivalent for example:

'' != 0 // -> false, i'd like true
'0' != 0 // -> false, and that's OK
null != false // -> true, and that's OK
undefined != null // -> false, but should be true (this case is not the priority)

Is there an efficient way to do that without listing all the cases manually?

user1579234
  • 501
  • 5
  • 15
Kaddath
  • 5,933
  • 1
  • 9
  • 23
  • Well I think you are sort of out of luck and would need to code something to do the checks for you. Why don't you convert it to strings or numbers to start and do not rely on the comparison to alter it. – epascarello Feb 11 '19 at 14:44
  • another composant does it, that i'd prefer not to go through for the moment because of its complexity, it's for a temporary fix – Kaddath Feb 11 '19 at 14:45

2 Answers2

1

you can use parseInt

const a = parseInt('') !== 0 // -> false, i'd like true
const b = parseInt('0') !== 0 // -> false, and that's OK
const c = parseInt(null) !== false // -> true, and that's OK
const d = parseInt(undefined) !== null // -> false, but should be true (this case is not the priority)
const x = parseInt(0) !== ''

console.log(a, b, c, d, x);
Taki
  • 17,320
  • 4
  • 26
  • 47
  • that could do part of the trick, except that the values are not in particular order (the stringified part can be on either side): `parseInt(0) != ''` is false :/ – Kaddath Feb 11 '19 at 14:55
  • how about checking the type ? using `!==` instead of `!=` ( updated answer ) – Taki Feb 11 '19 at 14:59
  • 1
    that's an idea, i'll test that, thanks for the answer – Kaddath Feb 11 '19 at 15:02
  • unfortunetly this one doesn't pass in the other order: `parseInt('0') !== 0` is false but `parseInt(0) !== '0'` is true.. but I wasn't exhaustive enough in my examples so that's not your fault, thanks angain, added the solution that suits me – Kaddath Feb 12 '19 at 15:04
  • oh my, got to review my stuff, it miserably fails for the same case than yours :D – Kaddath Feb 12 '19 at 15:17
0

After some tests (many failed because null has no properties, so no .toString and such) I found what suits, thanks to the help of Taki's answer, parseInt was the key thanks to NaN conversion. Original idea was just a simple traduction of the question itself in code: (a && a != b) || (!a && a !== b), but it fails with 0 and '0' in that particular order. So i went with this (test if a is truthy doesn't seem necessary): (a != b) || (!a && parseInt(a) !== parseInt(b))

function test(a, b){
  return (a != b) || (!a && parseInt(a) !== parseInt(b));
}

var a = test('', 0), // -> false, i'd like true
    b = test(0, ''),
    c = test(0, '0'), // -> false, and that's OK
    d = test('0', 0),
    e = test(null, false), // -> true, and that's OK
    f = test(false, null),
    g = test(undefined, null), // -> false, but should be true (this case is not the priority)
    h = test(null, undefined),
    i = test('', undefined), //all following are falsey and different, so true
    j = test(undefined, ''),
    k = test('', null),
    l = test(null, ''),
    m = test('0', undefined),
    n = test(undefined, '0'),
    o = test(null, '0'),
    p = test('0', undefined),
    q = test('1', true), //was not specified, but true is 1 in our DB, so false is OK
    r = test(true, '1'),
    s = test('42', 42), //also false, no change
    t = test(42, '42');

console.log(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t);
Kaddath
  • 5,933
  • 1
  • 9
  • 23