Подтвердить что ты не робот

Есть ли способ реализовать XOR в javascript

Я пытаюсь реализовать XOR в javascript следующим образом:

   // XOR validation
   if ((isEmptyString(firstStr) && !isEmptyString(secondStr)) ||
    (!isEmptyString(firstStr) && isEmptyString(secondStr))
   {
    alert(SOME_VALIDATION_MSG);
    return;
   }

Есть ли лучший способ сделать это в javascript?

Спасибо.

4b9b3361

Ответ 1

Я притворяюсь, что вы ищете логический XOR, поскольку у javascript уже есть побитовый (^) :)

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

if ((isEmptyString(firstStr) ? !isEmptyString(secondStr) 
                             : isEmptyString(secondStr))) {
alert(SOME_VALIDATION_MSG);
    return;
}

Редактировать:

работая на @Jeff фрикадельки Ян решения

if ((!isEmptyString(firstStr) ^ !isEmptyString(secondStr))) {
  alert(SOME_VALIDATION_MSG);
  return;
}

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

Ответ 2

Как указывали другие, логический XOR такой же, как и не равный для булевых, поэтому вы можете сделать это:


  // XOR validation
  if( isEmptyString(firstStr) != isEmptyString(secondStr) )
    {
      alert(SOME_VALIDATION_MSG);
      return;
    }

Ответ 3

Вы выполняете XOR логических значений, которые легко моделировать в побитом XOR (который имеет Javascript):

var a = isEmptyString(firstStr) ? 1 : 0;
var b = isEmptyString(secondStr) ? 1 : 0;

if(a ^ b) { ... }

http://www.howtocreate.co.uk/xor.html

Ответ 4

Вы можете напрямую использовать побитовый оператор XOR (^):

if (isEmptyString(firstStr) ^ isEmptyString(secondStr)) {
  // ...
}

Он будет работать для вашего примера, поскольку значения boolean true и false преобразуются в 1 и 0, потому что побитовые операторы работают с 32-разрядными целыми числами.

Это выражение вернет также либо 0, либо 1, и это значение будет принудительно возвращено в Boolean оператором if.

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

function xor(x, y) {
  return (x || y) && !(x && y);
}


if (xor(isEmptyString(firstStr), isEmptyString(secondStr))) {
  // ...
}

Ответ 5

Простейший метод:

if ((x+y) % 2) {
    //statement
}

предполагая, конечно, что обе переменные являются истинными булевыми, то есть 1 или 0.

  • Если x === y, вы получите четное число, поэтому XOR будет 0.
  • И если x !== y, то вы получите нечетное число, поэтому XOR будет 1:)

Второй вариант, если вы заметили, что x != y оценивается как XOR, все, что вам нужно сделать, это

if (x != y) {
    //statement
}

который будет просто оценивать снова как XOR. (Мне это нравится намного лучше)

Конечно, хорошей идеей было бы реализовать это в функции, но это ваш выбор.

Надеюсь, что любой из двух методов поможет кому-то! Я отмечаю этот ответ как вики сообщества, поэтому его можно улучшить.

Ответ 6

Оформить заказ это объяснение различных реализаций XOR в javascript.

Просто подведем итог нескольким из них прямо здесь:

if( ( isEmptyString(firstStr) || isEmptyString(secondStr)) && !( isEmptyString(firstStr) && isEmptyString(secondStr)) ) {
   alert(SOME_VALIDATION_MSG); 
   return; 
}

ИЛИ

if( isEmptyString(firstStr)? !isEmptyString(secondStr): isEmptyString(secondStr)) {
   alert(SOME_VALIDATION_MSG); 
   return;
}

ИЛИ

if( (isEmptyString(firstStr) ? 1 : 0 ) ^ (isEmptyString(secondStr) ? 1 : 0 ) ) {
   alert(SOME_VALIDATION_MSG); 
   return;
}

ИЛИ

if( !isEmptyString(firstStr)!= !isEmptyString(secondStr)) {
   alert(SOME_VALIDATION_MSG); 
   return;
}

Ответ 7

Цитата из эта статья:

К сожалению, JavaScript не имеет логического оператора XOR.

Вы можете "эмулировать" поведение оператора XOR с чем-то вроде:

if( !foo != !bar ) {
  ...
}

В связанной статье обсуждается несколько альтернативных подходов.

Ответ 8

XOR просто означает "эти два булевых значения разные?". Поэтому:

if (!!isEmptyString(firstStr) != !!isEmptyString(secondStr)) {
    // ...
}

!! - это просто гарантировать, что оператор != сравнивает два подлинных логических значения, так как предположительно isEmptyString() возвращает что-то другое (например, null для false или сама строка для true).

Ответ 9

Предполагая, что вы ищете BOOLEAN XOR, вот простая реализация.

function xor(expr1, expr2){
    return ((expr1 || expr2) && !(expr1 && expr2));
}

Приведенное выше вытекает из определения "исключительной дизъюнкции" {либо одного, но не обоих).

Ответ 10

Так как логические значения true и false преобразуются в 1 и 0 соответственно при использовании побитовых операторов на них, бит-XOR ^ может выполнять двойную работу как логический XOR, а также как битполеон, если ваши значения являются логическими значениями (Javascript "правдивые" значения не будут работать). Это легко осуществить с помощью оператора отрицания !.

a XOR b логически эквивалентен следующему (коротким) списку выражений:

!a ^ !b;
!a != !b;

Существует множество других форм, таких как !a ? !!b : !b, но эти два шаблона имеют преимущество только при оценке a и b после каждого (и не будут "короткозамкнуты", если a является ложным и, следовательно, не оценивает b), тогда как формы с использованием тернарных ?:, OR || или AND && операторов будут либо дважды оценены, либо короткозамкнуты.

Операторы отрицания ! в обоих утверждениях важны для включения по нескольким причинам: он преобразует все "истинные" значения в логические значения ( "- > false, 12 → true и т.д.), чтобы поразрядное оператор имеет значения, с которыми он может работать, поэтому оператор неравенства != сравнивает только значение истинности выражения (a != b не будет работать должным образом, если a или b были не равными, непустыми строками и т.д.), и поэтому каждая оценка возвращает результат с булевым значением вместо первого" правдивого" значения.

Вы можете продолжать расширять эти формы, добавляя двойные отрицания (или исключение, !!a ^ !!b, что по-прежнему эквивалентно XOR), но будьте осторожны, когда отрицаете только часть выражения. Эти формы могут казаться на первый взгляд "работать", если вы думаете о распределении в арифметическом (где 2(a + b) == 2a + 2b и т.д.), Но на самом деле производят разные таблицы истинности из XOR (они дают аналогичные результаты логическому NXOR):

!( a ^ b )
!( !!a ^ !!b )
!!a == !!b

Таким образом, общей формой для XOR может быть функция (таблица правды):

function xor( a, b ) { return !a ^ !b; }

И ваш конкретный пример:

if ( xor( isEmptyString( firstStr ), isEmptyString( secondStr ) ) ) { ... }

Или, если isEmptyString возвращает только логические значения и вам не нужна общая функция xor, просто:

if ( isEmptyString( firstStr ) ^ isEmptyString( secondStr ) ) { ... }

Ответ 11

Javascript не имеет логического оператора XOR, поэтому ваша конструкция кажется правдоподобной. Если бы это были числа, вы могли бы использовать побитовый оператор XOR.

веселит

Ответ 12

здесь XOR, который может вместить от двух до многих аргументов

function XOR() {
    for (var i = 1; i < arguments.length; i++) 
        if ( arguments[0] != arguments[i] ) 
            return false; 
    return true; 
}

Пример использования:

if ( XOR( isEmptyString(firstStr), isEmptyString(secondStr) ) ) {
    alert(SOME_VALIDATION_MSG);
    return;
}

Ответ 13

Я надеюсь, что это будет самый короткий и самый чистый

function xor(x,y){return true==(x!==y);}

Это будет работать для любого типа

Ответ 14

Вот функция XOR, которая принимает переменное количество аргументов (включая два). Аргументы должны быть только правдивыми или ложными, а не true или false.

function xor() {
    for (var i=arguments.length-1, trueCount=0; i>=0; --i)
        if (arguments[i])
            ++trueCount;
    return trueCount & 1;
}

В Chrome на моем MacBook 2007 он работает в течение 14 нс для трех аргументов. Как ни странно, эта немного другая версия принимает 2935 нс для трех аргументов:

function xorSlow() {
    for (var i=arguments.length-1, result=false; i>=0; --i)
        if (arguments[i])
            result ^= true;
    return result;
}

Ответ 15

Попробуйте следующее: function xor(x,y) var result = x || y if (x === y) { result = false } return result }

Ответ 16

Есть несколько методов, но тройственный метод (a? b: b) выглядит лучше всего. Кроме того, установка Boolean.prototype.xor представляется вариантом, если вам нужно часто выполнять xor.

http://jsperf.com/xor-implementations

Ответ 17

Вы можете сделать это:

Math.abs( isEmptyString(firstStr) - isEmptyString(secondStr) )

Результатом этого является результат операции XOR.

Ответ 18

@george, мне нравится ваша функция для ее возможности принимать более двух операндов. У меня есть небольшое улучшение, чтобы заставить его быстрее возвращаться:

function xor() {
    for (var i=arguments.length-1, trueCount=0; i>=0; --i)
        if (arguments[i]) {
            if (trueCount)
                return false
            ++trueCount;
        }
    return trueCount & 1;
}