Ternary Comparison Assignment Operators


While building an app, I came across this code...

sortOrder = sortOrder === "asc" ? "desc" : "asc";

This is a bit repetitive and gets larger respective to the variable's name.

My idea is to have a kind of ternary assignment operator that looks something like this...

[variable] ?[comparison-operator] [expression1]: [expression2];

In action...

sortOrder ?=== "asc": "desc";

If sortOrder is asc this would make it desc, if it's not it would make it asc.


?=== // Ternary Strict Equality Assigner
?==  // Ternary Equality Assigner
?!== // Ternary Strict Inequality Assigner
?!=  // Ternary Inequality Assigner
?>   // Ternary Greater Than Assigner
?>=  // Ternary Greater Than or Equal To Assigner
?<   // Ternary Less Than Assigner
?<=  // Ternary Less Than or Equal To Assigner

Personally, I don't like this syntax so I'll look forward to your ideas :)

I think it's better to give this kind of operation a name:

const flipSortOrder = o => o === "asc" ? "desc" : "asc";

Because at some point, someone's gonna be surprised that "ASC" and "DESC" both become "asc", and you'll be happy there's a single place to make the test case-insensitive.

And then with pipeline operator...

sortOrder |>= flipSortOrder;
1 Like

A more general-purpose solution could be a self-assignment version of the pipeline operator ("|>="). From what I know, there aren't any plans to do that kind of thing, but I've heard people around express a desire for such an operator.

sortOrder |>= % === "asc" ? "desc" : "asc"
// same as
sortOrder = sortOrder |> % === "asc" ? "desc" : "asc"
// same as
sortOrder = (x => x === "asc" ? "desc" : "asc")(sortOrder)

Personally, I would solve this differently using a cyclic list sort of thing.

const sortOrders = ['asc', 'desc']
const currentSortOrder = 'asc'
const newSortOrder = cycleList(sortOrders, currentSortOrder)
// newSortOrder === 'desc'

This can also be used more generically with longer lists like ['asc', 'desc', 'custom'].

Also, a third optional object parameter could be introduced to cycle backwards or more than one step at a time.

const newSortOrder = cycleList(
  { direction: 'back', steps: 3 }

But I don't know if this would be better as a library. Maybe as part of the standard library proposal?