Троичные операторы с более чем одной переменной

#javascript #operators #ternary

#javascript #операторы #троичный

Вопрос:

Я познакомился с концепцией троичных операторов, и понять их обозначение довольно просто:

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

Однако я не смог понять рациональное обоснование добавления второй переменной, даже если я понимаю ответ. Чтобы использовать классический пример:

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

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

Здесь одно наблюдение: если я изменю порядок переменных на приведенную ниже инструкцию, функция не будет работать:

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

Мой вопрос: почему функция не работает, когда термины инвертируются? И как мне выбрать порядок терминов, когда у меня есть две или более переменных (и, следовательно, четыре или более результатов)?

Комментарии:

1. в одном троичном файле есть только один вопросительный знак и двоеточие, например variable = comparison ? value1 : value2;

2. В общем, если ваш троичный оператор не является супер простым, вам, вероятно, следует избегать написания логики в виде троичного оператора и просто делать if/else вместо этого. Нет никакого преимущества в том, чтобы поместить все в одну строку, если вам потребуется больше времени, чтобы прочитать и понять, что это происходит.

3. Я согласен с тем, что if / else было бы понятнее. Проблема в том, что я пытаюсь добиться логического мышления больше, чем конечного результата.

Ответ №1:

Троичные выражения содержат внутри себя 3 выражения. Однако, поскольку троичные выражения сами по себе являются выражениями, вы можете поместить троичные выражения внутрь других троичных выражений. Троичные выражения в вашем примере выше выглядят настолько запутанными, потому что они представляют собой несколько вложенных троичных выражений. Эту путаницу можно лучше устранить с помощью форматирования и использования круглых скобок:

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

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

Ответ №2:

Вы можете понять это на этом примере.

 x ? ( y ? a : b ) : c
|
|________true   ---> y ? a : b
|
|________false  ---> c
  
  • сначала проверьте значение, x если оно true, оно будет запущено y ? a : b (я добавил () просто для удобства чтения)
  • Если значение равно false, оно перейдет к c

Вы можете просто понять это так же, как if / else, если я изменю приведенный выше код на if / else

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

Комментарии:

1. Спасибо, это мне очень помогло.

Ответ №3:

Чтобы получить правильный результат, вы могли бы сгруппировать троичные операторы и поддерживать одинаковый уровень решений.

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

console.log(category);  

Ответ №4:

Вы не можете изменить порядок между then и else частями, поскольку это влияет на результат (если вы также не отмените условие). Однако вы можете изменить вложенность и написать либо

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

или

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

Ответ №5:

Троичная операция всегда принимает три операнда, например:

 inputExpression ? outputExpressionIfTrue : outputExpressionIfFalse
  

Код в вопросе использует выходные данные некоторых троичных операций в качестве входного выражения для других, что можно увидеть более четко, если мы отформатируем его, как в этом фрагменте кода. В каждом случае внешняя операция возвращает результат любой выполняемой внутренней операции (и комментарии объясняют, какая внутренняя операция выполняется и что она возвращает.)

 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);  

Обратите внимание, что для обработки информации о категориях объектов со схожими свойствами может быть полезно использовать объекты, такие как:

 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);