admin管理员组

文章数量:1022843

I have been introduced to the concept of ternary operators, and it's pretty straightforward to understand the notation:

desired_variable = true ? false ? "value1" : "value2";

I could not understand, however, the rational behind adding a second variable, even if I understand the answer. To use a classic example:

var eatsPlants = false;
var eatsAnimals = false;
var category;

category = eatsPlants ? eatsAnimals ? "omnivore" : "herbivore" : eatsAnimals ? "carnivore" : undefined;
console.log(category)

Here, one observation: If I change the order of the variables to the statement below, the function does not work:

category = eatsAnimals ? eatsPlants? "carnivore" : undefined : eatsPlants ? "herbivore" : "omnivore";
console.log(category)

My question: why doesn't the function work when the terms are inverted? And how do I choose the order of the terms when I have two or more variables (and therefore four or more results)?

I have been introduced to the concept of ternary operators, and it's pretty straightforward to understand the notation:

desired_variable = true ? false ? "value1" : "value2";

I could not understand, however, the rational behind adding a second variable, even if I understand the answer. To use a classic example:

var eatsPlants = false;
var eatsAnimals = false;
var category;

category = eatsPlants ? eatsAnimals ? "omnivore" : "herbivore" : eatsAnimals ? "carnivore" : undefined;
console.log(category)

Here, one observation: If I change the order of the variables to the statement below, the function does not work:

category = eatsAnimals ? eatsPlants? "carnivore" : undefined : eatsPlants ? "herbivore" : "omnivore";
console.log(category)

My question: why doesn't the function work when the terms are inverted? And how do I choose the order of the terms when I have two or more variables (and therefore four or more results)?

Share Improve this question edited Mar 10, 2019 at 4:43 pretzelhammer 15.2k16 gold badges54 silver badges104 bronze badges asked Mar 9, 2019 at 19:16 cgobbetcgobbet 3191 gold badge4 silver badges13 bronze badges 3
  • there is only one questionmark and colon in a single ternary, like variable = parison ? value1 : value2; – Nina Scholz Commented Mar 9, 2019 at 19:18
  • 1 In general, if your ternary operator is not super simple, you should probably avoid writing the logic as a ternary operator and just do if/else instead. There is no advantage to having all in one line if it takes you any longer to read and understand what it happening. – VLAZ Commented Mar 9, 2019 at 19:20
  • I agree abour the if/else would be clearer. The issue is that I am trying to get the logical thinking more than the final oute. – cgobbet Commented Mar 10, 2019 at 9:53
Add a ment  | 

5 Answers 5

Reset to default 4

Ternary expressions have 3 expressions inside of them. However, because ternary expressions are themselves expressions you can put ternary expressions inside other ternary expressions. The ternary expressions in your example above look so confusing because they are multiple nested ternary expressions. This confusion can be better cleared up with formatting and use of parentheses:

var eatsPlants = false;
var eatsAnimals = false;
var category = null;

category =
  (eatsPlants ?
    (eatsAnimals ? "omnivore" : "herbivore")
    :
    (eatsAnimals ? "carnivore" : undefined)
  );
console.log(category);

You can understand by this example.

x ? ( y ? a : b ) : c
|
|________true   ---> y ? a : b
|
|________false  ---> c
  • first check the value of x if it is true it will run y ? a : b (i have added () just for readability )
  • If it is false it will go to c

You can simply understand it same as if/else, if i change above code to if/else

if(x){
  if(y) {
    return a
  } else {
    return b
} else {
   return c
 }
}

To get a right result, you could group the ternaries and maintain the same level of decisions.

var eatsPlants = false,
    eatsAnimals = false,
    category = eatsPlants
        ? eatsAnimals
            ? "omnivore"
            : "herbivore"
        : eatsAnimals
            ? "carnivore"
            : undefined;

console.log(category);

You cannot change the order between then and else parts, as that affects the oute (if you don't also negate the condition). You can however change the nesting, and write either

category = eatsPlants
  ? eatsAnimals
      ? "omnivore"
      : "herbivore"
  : eatsAnimals
      ? "carnivore"
      : undefined;

or

category = eatsAnimals
  ? eatsPlants
      ? "omnivore"
      : "carnivore"
  : eatsPlants
      ? "herbivore"
      : undefined;

A ternary operation always takes three operands, like:

inputExpression ? outputExpressionIfTrue : outputExpressionIfFalse

The code in the question is using the output from some ternary operations as the input expression for others, which can be seen more clearly if we format it like in this code snippet. In each case, the outer operation returns the result of whichever inner operation runs (and the ments explain which inner operation runs and what it returns.)

var eatsPlants = false;
var eatsAnimals = false;
var category;

category = eatsPlants
  ? (eatsAnimals ? "omnivore" : "herbivore") // doesn't run because eatsPlants is false
  : (eatsAnimals ? "carnivore" : undefined); //returns undefined because eatsAnimals is false 
console.log(category);

category = eatsAnimals
 ? (eatsPlants ? "carnivore" : undefined) // doesn't run because eatsAnimals is false
 : (eatsPlants ? "herbivore" : "omnivore"); // returns "omnivore" because eatsPlants is false
console.log(category);

Note that to handle information about categories of things with similar properties, it may be helpful to use objects, like:

const carnivore =  {
  eatsPlants: false,
  eatsAnimals: true
};
const herbivore =  {
  eatsPlants: true,
  eatsAnimals: false
};
const omnivore =  {
  eatsPlants: true,
  eatsAnimals: true
};

console.log("carnivore:");
console.log("  eatsPlants: " + carnivore.eatsPlants);
console.log("  eatsAnimals: " + carnivore.eatsAnimals);
console.log("herbivore:");
console.log("  eatsPlants: " + herbivore.eatsPlants);
console.log("  eatsAnimals: " + herbivore.eatsAnimals);
console.log("omnivore:");
console.log("  eatsPlants: " + omnivore.eatsPlants);
console.log("  eatsAnimals: " + omnivore.eatsAnimals);  

I have been introduced to the concept of ternary operators, and it's pretty straightforward to understand the notation:

desired_variable = true ? false ? "value1" : "value2";

I could not understand, however, the rational behind adding a second variable, even if I understand the answer. To use a classic example:

var eatsPlants = false;
var eatsAnimals = false;
var category;

category = eatsPlants ? eatsAnimals ? "omnivore" : "herbivore" : eatsAnimals ? "carnivore" : undefined;
console.log(category)

Here, one observation: If I change the order of the variables to the statement below, the function does not work:

category = eatsAnimals ? eatsPlants? "carnivore" : undefined : eatsPlants ? "herbivore" : "omnivore";
console.log(category)

My question: why doesn't the function work when the terms are inverted? And how do I choose the order of the terms when I have two or more variables (and therefore four or more results)?

I have been introduced to the concept of ternary operators, and it's pretty straightforward to understand the notation:

desired_variable = true ? false ? "value1" : "value2";

I could not understand, however, the rational behind adding a second variable, even if I understand the answer. To use a classic example:

var eatsPlants = false;
var eatsAnimals = false;
var category;

category = eatsPlants ? eatsAnimals ? "omnivore" : "herbivore" : eatsAnimals ? "carnivore" : undefined;
console.log(category)

Here, one observation: If I change the order of the variables to the statement below, the function does not work:

category = eatsAnimals ? eatsPlants? "carnivore" : undefined : eatsPlants ? "herbivore" : "omnivore";
console.log(category)

My question: why doesn't the function work when the terms are inverted? And how do I choose the order of the terms when I have two or more variables (and therefore four or more results)?

Share Improve this question edited Mar 10, 2019 at 4:43 pretzelhammer 15.2k16 gold badges54 silver badges104 bronze badges asked Mar 9, 2019 at 19:16 cgobbetcgobbet 3191 gold badge4 silver badges13 bronze badges 3
  • there is only one questionmark and colon in a single ternary, like variable = parison ? value1 : value2; – Nina Scholz Commented Mar 9, 2019 at 19:18
  • 1 In general, if your ternary operator is not super simple, you should probably avoid writing the logic as a ternary operator and just do if/else instead. There is no advantage to having all in one line if it takes you any longer to read and understand what it happening. – VLAZ Commented Mar 9, 2019 at 19:20
  • I agree abour the if/else would be clearer. The issue is that I am trying to get the logical thinking more than the final oute. – cgobbet Commented Mar 10, 2019 at 9:53
Add a ment  | 

5 Answers 5

Reset to default 4

Ternary expressions have 3 expressions inside of them. However, because ternary expressions are themselves expressions you can put ternary expressions inside other ternary expressions. The ternary expressions in your example above look so confusing because they are multiple nested ternary expressions. This confusion can be better cleared up with formatting and use of parentheses:

var eatsPlants = false;
var eatsAnimals = false;
var category = null;

category =
  (eatsPlants ?
    (eatsAnimals ? "omnivore" : "herbivore")
    :
    (eatsAnimals ? "carnivore" : undefined)
  );
console.log(category);

You can understand by this example.

x ? ( y ? a : b ) : c
|
|________true   ---> y ? a : b
|
|________false  ---> c
  • first check the value of x if it is true it will run y ? a : b (i have added () just for readability )
  • If it is false it will go to c

You can simply understand it same as if/else, if i change above code to if/else

if(x){
  if(y) {
    return a
  } else {
    return b
} else {
   return c
 }
}

To get a right result, you could group the ternaries and maintain the same level of decisions.

var eatsPlants = false,
    eatsAnimals = false,
    category = eatsPlants
        ? eatsAnimals
            ? "omnivore"
            : "herbivore"
        : eatsAnimals
            ? "carnivore"
            : undefined;

console.log(category);

You cannot change the order between then and else parts, as that affects the oute (if you don't also negate the condition). You can however change the nesting, and write either

category = eatsPlants
  ? eatsAnimals
      ? "omnivore"
      : "herbivore"
  : eatsAnimals
      ? "carnivore"
      : undefined;

or

category = eatsAnimals
  ? eatsPlants
      ? "omnivore"
      : "carnivore"
  : eatsPlants
      ? "herbivore"
      : undefined;

A ternary operation always takes three operands, like:

inputExpression ? outputExpressionIfTrue : outputExpressionIfFalse

The code in the question is using the output from some ternary operations as the input expression for others, which can be seen more clearly if we format it like in this code snippet. In each case, the outer operation returns the result of whichever inner operation runs (and the ments explain which inner operation runs and what it returns.)

var eatsPlants = false;
var eatsAnimals = false;
var category;

category = eatsPlants
  ? (eatsAnimals ? "omnivore" : "herbivore") // doesn't run because eatsPlants is false
  : (eatsAnimals ? "carnivore" : undefined); //returns undefined because eatsAnimals is false 
console.log(category);

category = eatsAnimals
 ? (eatsPlants ? "carnivore" : undefined) // doesn't run because eatsAnimals is false
 : (eatsPlants ? "herbivore" : "omnivore"); // returns "omnivore" because eatsPlants is false
console.log(category);

Note that to handle information about categories of things with similar properties, it may be helpful to use objects, like:

const carnivore =  {
  eatsPlants: false,
  eatsAnimals: true
};
const herbivore =  {
  eatsPlants: true,
  eatsAnimals: false
};
const omnivore =  {
  eatsPlants: true,
  eatsAnimals: true
};

console.log("carnivore:");
console.log("  eatsPlants: " + carnivore.eatsPlants);
console.log("  eatsAnimals: " + carnivore.eatsAnimals);
console.log("herbivore:");
console.log("  eatsPlants: " + herbivore.eatsPlants);
console.log("  eatsAnimals: " + herbivore.eatsAnimals);
console.log("omnivore:");
console.log("  eatsPlants: " + omnivore.eatsPlants);
console.log("  eatsAnimals: " + omnivore.eatsAnimals);  

本文标签: javascriptTernary operators with more than one variableStack Overflow