簡體   English   中英

無論如何在javascript中實現XOR

[英]Is there anyway to implement XOR in javascript

我試圖通過以下方式在javascript中實現XOR:

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

有沒有更好的方法在JavaScript中執行此操作?

謝謝。

正如其他人所指出的那樣,邏輯XOR對於布爾值來說是不相等的,所以你可以這樣做:


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

我假裝你正在尋找一個邏輯XOR,因為javascript已經有一個按位(^):)

我通常使用一個簡單的三元運算符(我很少使用其中一個):

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

編輯:

致力於@Jeff Meatball Yang 解決方案

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

你否定了值以便在布爾值中轉換它們然后應用按位xor運算符。 也許它不像第一個解決方案那么可維護(或者我可能已經習慣了第一個解決方案)

你正在做一個布爾值的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

您可以直接使用按位XOR運算符( ^ ):

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

它將適用於您的示例,因為布爾值truefalse值被轉換為10因為按位運算符使用32位整數。

該表達式也將返回01 ,並且該值將由if語句強制回布爾值。

您應該知道上述方法發生的類型強制,如果您正在尋找良好的性能,我不建議您使用按位運算符,您也可以使用僅邏輯邏輯來創建一個簡單的函數運營商:

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


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

一種方法更簡單:

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

當然假設兩個變量都是真正的布爾值,即10

  • 如果x === y你會得到一個偶數,所以XOR將為0
  • 如果x !== y那么你會得到一個奇數,所以XOR將是1 :)

第二種選擇,如果您注意到x != y計算結果是異或,那么您必須做的就是

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

這將再次評估為異或。 (我更喜歡這個)

當然,一個好主意是將它實現為一個函數,但它只是你的選擇。

希望這兩種方法中的任何一種都能幫到別 我將此答案標記為社區維基,因此可以進行改進。

在javascript中查看XOR的不同實現的這種解釋。

只是在這里總結一些:

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

從引用文章:

不幸的是,JavaScript沒有邏輯XOR運算符。

您可以通過以下方式“模擬”XOR運算符的行為:

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

鏈接的文章討論了幾種替代方法。

假設您正在尋找BOOLEAN XOR,這是一個簡單的實現。

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

以上來源於“獨占分離”的定義{任一個,但不是兩個}。

由於布爾值truefalse在使用按位運算符時分別轉換為10 ,因此只要值為布爾值,bitwise-XOR ^就可以作為邏輯XOR和bitwiseone執行雙重任務( Javascript的“truthy”值不會起作用)。 否定就容易實現這一點! 運營商。

a XOR b在邏輯上等同於以下(短)表達式列表:

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

還有很多其他形式 - 例如!a ? !!b : !b !a ? !!b : !b - 但是這兩種模式的優點是只評估ab一次(並且如果a是假的則不會“短路”,因此不評估b ),而使用三元的形式?: ,或者|| 或AND &&運算符將進行雙重評估或短路。

否定! 兩個語句中的運算符很重要,包括幾個原因:它將所有“truthy”值轉換為布爾值(“” - > false,12 - > true等),以便按位運算符具有可以使用的值,所以不等式!=運算符只比較每個表達式的真值(如果ab不相等,非空字符串等,則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 ) ) { ... }

XOR只是意味着“這兩個布爾值是不同的嗎?”。 因此:

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

!! s只是為了保證!=運算符比較兩個真正的布爾值,因為可以想象isEmptyString()返回其他內容(如nullnull ,或者字符串本身為true)。

我希望這將是最短最干凈的

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

這適用於任何類型

Javascript沒有邏輯XOR運算符,因此您的構造似乎是合理的。 如果它是數字,那么你可以使用^即按位XOR運算符。

干杯

這是一個可以容納兩個到多個參數的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;
}

這是一個XOR函數,它接受可變數量的參數(包括兩個)。 爭論只需要truefalse ,不是truefalse

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

在我的2007 MacBook上的Chrome上,它在14 ns內運行三個參數。 奇怪的是,這個略有不同的版本需要2935 ns的三個參數:

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

試試這個: function xor(x,y) var result = x || y if (x === y) { result = false } return result } function xor(x,y) var result = x || y if (x === y) { result = false } return result }

有幾種方法,但三元方法(a?!b:b)似乎表現最佳。 此外,如果您需要經常使用xor,設置Boolean.prototype.xor似乎是一個選項。

http://jsperf.com/xor-implementations

你可以這樣做:

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

結果是XOR運算的結果。

@george,我喜歡你的功能,因為它能夠接收2個以上的操作數。 我有一點點改進,使它恢復得更快:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM