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
- I use the ternary symbol inside async/await
- If the sum is greater than 10 I return true, if less than 10 I return false
reference
An idea ... Ternary Comparison Assignment Operators with Negation opperator
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.`);
Notes
- Only ideas