質問

次の方法でjavascriptにxorを実装しようとしています。

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

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

ありがとう。

役に立ちましたか?

解決

JavaScriptがすでに少し(^):)を持っているので、私はあなたが論理的なxorを探しているふりをしています:)

私は通常、単純な三元演算子を使用します(私が使用するまれな時期の1つ):

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 validation
  if( isEmptyString(firstStr) != isEmptyString(secondStr) )
    {
      alert(SOME_VALIDATION_MSG);
      return;
    }

Bitise xor(JavaScriptが持っている)に簡単にモデル化するのが簡単なブール値のXORを実行しています。

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

if(a ^ b) { ... }

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

BitWise XORオペレーターを使用できます(^) 直接:

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

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

その表現も戻ります 0 また 1, 、そしてその価値は、 if 声明。

上記のアプローチで発生するタイプの強制に注意する必要があります。良いパフォーマンスを探している場合は、Bitwiseオペレーターと連携することをお勧めしません。また、Boolean Logicalのみを使用して簡単な機能を作成することもできます。オペレーター:

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


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

簡単な方法:

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つの方法のいずれかが誰かを助けることを願っています!この答えをコミュニティウィキとしてマークしているため、改善できます。

チェックアウト これ 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 ) {
  ...
}

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

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

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

!!sは、それを保証するためだけです != オペレーターは、おそらく2つの本物のブール値を比較します isEmptyString() 何か他のものを返します(次のように null 偽の場合、またはtrueの文字列自体)。

ブールXORを探していると仮定すると、ここに簡単な実装があります。

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

上記は、「排他的な分離」{どちらかではなく}の定義に由来します。

ブール値以来 truefalse に変換されます 10 それぞれビットワイズ演算子を使用する場合、bitwise-xor ^ あなたの値がブール値である限り(JavaScriptの「Truthy」値が機能しない限り、論理XORとBitWiseOneとして二重勤務を行うことができます。これは否定で簡単に痛むことができます ! オペレーター。

a XOR b 次の(短い)式のリストと論理的に同等です。

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

可能な他の多くのフォームがあります - !a ? !!b : !b - しかし、これらの2つのパターンには、評価するだけの利点があります ab それぞれが一度(そして、「短絡」もしない場合は a 偽りであるため、評価しません b)、一方、三元を使用しています ?:, 、 また ||, 、 または && オペレーターは、二重回路または短絡のいずれかです。

否定 ! 両方のステートメントのオペレーターは、いくつかの理由で含めることが重要です。すべての「真実」値をブール値( "" - > 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 ) ) { ... }

JavaScriptには論理的なXOR演算子がないため、構成要素はもっともらしいと思われます。数字だったら、 ^すなわちビットワイズXOR演算子を使用できたでしょう。

乾杯

これが2つから多くの議論に対応できる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;
}

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

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

これは任意のタイプで機能します

これは、さまざまな数の引数を取得するXOR関数です(2つを含む)。議論は真実またはfalsyであるだけでなく、 true また false.

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

2007年のMacBookのChromeでは、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;
}

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

いくつかの方法がありますが、三元メソッド(a?!b:b)が最適に機能するようです。また、boolean.prototype.xorの設定は、頻繁に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帰属
所属していません StackOverflow
scroll top