web-dev-qa-db-ja.com

とにかくJavaScriptでXORを実装することはありますか

私は次のようにJavaScriptでXORを実装しようとしています:

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

これをJavaScriptで行うより良い方法はありますか?

ありがとう。

41
amoran

Javascriptにはすでにビット単位のものがあるため(^):)、論理XORを探していると思います。

私は通常、単純な三項演算子を使用します(私が使用することはまれです)。

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

編集:

@Jeff Meatball Yangに取り組んでいます solution

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

ブール値に変換するために値を否定し、ビット単位のxor演算子を適用します。たぶん、最初の解決策ほどメンテナンスが難しいかもしれません(または私は最初の解決策に慣れすぎているかもしれません)

34
Eineki

他の人が指摘したように、論理XORはブール値の等しくないと同じなので、これを行うことができます:


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

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

11

ビット単位のXOR演算子(^)を直接使用できます。

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

ブール値truefalseの値は10に変換されるため、ビットワイズ演算子は32ビット整数で動作するため、これは例として機能します。

その式は0または1も返し、その値はifステートメントによってブール値に強制的に戻されます。

上記のアプローチで発生する型強制に注意する必要があります。優れたパフォーマンスを求めている場合は、ビット演算子を使用することはお勧めしません。ブール論理のみを使用して簡単な関数を作成することもできます。演算子:

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


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

より簡単な1つの方法:

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

もちろん、両方の変数が真のブール値、つまり1または0

  • x === y偶数を取得するため、XORは0
  • で、もし x !== yすると奇数になるので、XORは1 :)

2番目のオプション、x != yはXORとして評価され、次に実行する必要があるのは

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

XORとして評価されます。 (私はこれがずっと好きです)

もちろん、いいアイデアはこれを関数に実装することですが、それはあなたの選択だけです。

2つの方法のいずれかが誰かを助けることを願っています!私はこの回答をコミュニティウィキとしてマークしているので、改善することができます。

7
Nico

チェックアウト this JavaScriptのXORのさまざまな実装の説明。

それらのいくつかをここで要約すると:

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

OR

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

OR

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

OR

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

this 記事からの引用:

残念ながら、JavaScriptには論理XOR演算子がありません。

XOR演算子の動作を次のようなもので「エミュレート」できます。

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

リンクされた記事では、いくつかの代替アプローチについて説明しています。

5
Roberto Aloi

ブール値trueおよびfalseは、ビット単位演算子を使用すると、それぞれ_1_および_0_に変換されるため、ビット単位XOR _^_は、論理値としての二重義務XORと同様に、値がブール値である限り(Javascriptの「真の」値は機能しません)これは否定__!_演算子。

_a XOR b_は、式の次の(短い)リストと論理的に同等です。

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

_!a ? !!b : !b_など、他にも多くの形式が考えられますが、これらの2つのパターンには、abをそれぞれ1回だけ評価するという利点があります(「短絡」しない)また、aがfalseであり、したがってb)を評価しない場合、3項_?:_、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 ) ) { ... }
_
2
Brian North

XORは、「これらの2つのブール値は異なるのか」という意味です。したがって:

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

!!sは、!=演算子が2つの真のブール値を比較することを保証するためのものです。おそらく、isEmptyString()は何か他のものを返します(falseの場合はnull、trueの場合は文字列自体)。

2
Sean

BOOLEAN XORを探していると仮定して、簡単な実装を次に示します。

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

上記は、「排他的選言」{どちらか一方、両方ではない}の定義から派生しています。

2
Butshuti Hakiza

Javascriptには論理的なXOR演算子がないため、構成が妥当であるように思われます。それが数値であった場合、^つまりビット単位XOR演算子を使用できます。

乾杯

1
Arnkrishn

XORは2つから多くの引数に対応できます。

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;
}
1
some young guy

これが最も短くてきれいなものになることを願っています

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

これはどのタイプでも機能します

1

@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;
}
0
elfan

これを試してください:function xor(x,y) var result = x || y if (x === y) { result = false } return result }

0
Gavriel Feria

いくつかの方法がありますが、3種類の方法(a?!b:b)が最も効果的です。また、頻繁にXORする必要がある場合は、Boolean.prototype.xorの設定がオプションのように見えます。

http://jsperf.com/xor-implementations

0
Fordi

あなたはこれを行うことができます:

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

その結果は、XOR演算の結果です。

0
Zack

以下はXOR関数で、引数の数は2つです(2つを含む)。引数はtrueまたはfalseではなく、真または偽である必要があります。

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

Chrome私の2007 MacBookでは、3つの引数で14 nsで動作します。奇妙なことに、このわずかに異なるバージョンでは、3つの引数で2935 nsかかります。

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