# Ternary Comparison Assignment Operators

Hi,

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`.

## Variations

``````?=== // 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)
``````
2 Likes

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(
sortOrders,
currentSortOrder,
{ 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?

You should definitely keep the index instead of a literal for what you called a cycle list:

``````class CycleList {
constructor(array) {
this.array = array;
this.value = 0;
}
get curr() {
return this.array[this.value %% this.array.length];
}
get next() {
return this.array[++this.value %% this.array.length];
}
get prev() {
return this.array[--this.value %% this.array.length];
}
step(offset) {
return this.array[(this.value += offset) %% this.array.length];
}
*[Symbol.iterator]() {
while (true) {
yield this.next;
}
}
}
const list = new CycleList(["ascending", "descending", "unspecified"]);
list.curr; // "ascending"
list.next; // "descending"
list.step(-2); // "unspecified"
``````

Notice that it uses the proposed Modulo Operator %%.

Actually the point is, one (including myself) may not want to repeat the string literal especially when it’s very long; and there are risks of misspelling them (unless you use TypeScript):

``````sortOrder = sortOrder == "dictionarySortedInAscendingOrder" ? "dictionarySortedInDescendingOrder" : "dictionarySortedInAscendingOrder";
``````

So, my advice is to keep a boolean instead of a string variable:

``````const orders = ["asc", "desc"];
let sortDesc = false;
// then
sortDesc = !sortDesc;
orders[+sortDesc]; // "desc"
// or in a single line:
orders[+(sortDesc = !sortDesc)];
``````

@ethanlal04 @lightmare @graphemecluster @alinnert @theScottyJam
Hi all! Is it possible to do that? ternary Comparison Assignment Operators with Pipeline tap operator `|:` ?

#### case... my idea ... an idea:

``````const doTransfomration = data => data
.filter(x => x != null)
.tap(x => console.log(x))
.sortOrder ?=== .map(x => x ** 2) or .filter(x => x > 100);
``````

#### reference

@ethanlal04 @theScottyJam @lightmare @lightmare @graphemecluster @alinnert Hi all! Is it possible to do that? ternary Comparison Assignment Operators with Concurrent Async and Normal Await Evaluation Blocks.

#### case... my idea ... an idea:

``````async function sum(variable1, variable2) => {
const a = async getA(variable1);
const b = async getB(variable2);
/* ... */
return   ?=== a(variable1)+b(variable2)>10 or "false";
}

sum(2, 3);// 2+3=5 // false
sum(10, 10); // 10+10=20 // true
``````

#### Notes

1. I use the ternary symbol inside async/await
2. If the sum is greater than 10 I return true, if less than 10 I return false

#### case1.js

``````let value = 10

// check the condition
if (value >= 11) ? value++ : value--; // if pass... increment value++ // if fail ... decrement value

// program to check pass or fail
console.log(`You \${value} the exam.`);
``````

#### case2.js

``````let value = 10

// check the condition
if (value >= 11) ? !false : value^^; // if pass... increment value++ // if fail ... decrement value

// program to check pass or fail
console.log(`You \${value} the exam.`);
``````

1. Only ideas