Hacker News new | ask | show | jobs
by XCSme 2265 days ago
I think you can just do:

    if (cellA > cellB) return 1;
    if (cellA < cellB) return -1;
    if (cellA === cellB) return 0;
Why is the switch better? Or even (less explicit, but shorter code):

    if (cellA === cellB) return 0;
    return cellA > cellB ? 1 : -1;
4 comments

Switch statements indicate "it's one of these things", whereas in the series of ifs any of them could be true. Using a switch statement tells the reader that you expect one of these things to happen [0]. Using a series of ifs tells the reader that these things might or might not happen depending, and they're going to have to read each statement to work out which.

Your last version doesn't tell the reader what your intention is at all, and they need to work out what you're trying to do here. It's a lot less readable. Unless you're desperate for those bytes, it'd be better to use the switch statement for this case.

[0]: This gets a little weird in languages like JS where switch statements fall through to the next one if you don't break or return, but generally it still holds true.

That's not how switches work: a switch can (and will) trigger lots of cases if you don't either `break` (highly unintuitive to new programmers, who like you believe switch is "do one of these") or `return`, either of which cuts cuts the switch short.
I don't think this line of reasoning makes sense, since as you acknowledge, JS switch has fallthrough. I would not immediately assume that the coder's intent was for only one branch to execute if I came across a 'switch' in some JS code.
Adding 'else's to the above code would make it superior to switch by these metrics (e.g. no fallthrough).
You should not use switch in JavaScript, because it is a language where switch requires break, which means it's 100% going to bite you in the ass unless you have a linter that checks for the break. It's not worth it for such a simple case.
With if you can also indicate "it's one of these things" by throwing an error at the end:

    if (cellA > cellB) return 1;
    if (cellA < cellB) return -1;
    if (cellA === cellB) return 0;
    throw new Error();
Let me tell you about if..else!
hah, well then you can of course continue...

    return (cellA === cellB) ? 0 : (cellA > cellB ? 1 : -1);
Keep going:

    return (cellA > cellB) * 1 + (cellA < cellB) * -1;
More:

    return Math.sign(cellA - cellB);
You don't need the * 1 multiplication:

   return (cellA > cellB) - (cellA < cellB);
does work for NaN... rookie mistake, eh
Math.sign trick doesn't work for strings.
That's true, but the default string comparison sometimes isn't that useful, right? I somehow assumed the data is numbers only, rookie mistake :)

    'ana' > 'Bob'
    '2' > '123'
You usually want to clearly define the order or pre-process the strings in some way (trim them, same casing, etc).
Well, you can pass the strings through .toUpperCase() before comparing them.

Or indeed drop the <, > based approach and use: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Or: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

honestly? i like it. properly formatted it looks alright:

    return (
      (cellA === cellB) ? 0 :
      (cellA >   cellB) ? 1 :
      -1
    );
and it's an expression, so i immediately know it won't do any weird control flow. i'd prefer "if/then/else" vs "?/:" but it's not bad
This works fine if the ? operator is right-associative, but in PHP it's left-associative and you have a subtle bug.

I find a better indendation style for this is more like

    condition
        ? truthy
        : falsy
i use that style too sometimes, depends on what's clearer. IME the former usually works better if you have a multiple tests, but the latter is the only readable option if you need to break a case across lines.

yeah, ternary-if is busted in php :/ (far from the only thing that's busted there though...) i'm actually doing some PHP work right now, and never chain ifs to avoid this exact thing.

It makes it clear that you're going to execute only one of the possibilities. Maybe that's clearer than a page full of ifs. But yeah, not particularly fond of the idea.
Except JavaScript switch has fallthrough, so it doesn’t make that clear at all. (Sure, no fallthrough happens with return in each case, but neither would a bunch of plain if ... return.)
both fragments are incorrect for NaN...

The correct is return a<b?-1: (a>b? 1 :0)

var a=NaN, b=1; a<b ? -1 : (a>b ? 1 : 0); // 0

var a="a", b=1; a<b ? -1 : (a>b ? 1 : 0); // 0

The switch and if statements would return undefined in these cases. Or others threw an error if none of the conditions matched, that would work too.