とにかくJavaScriptにXORを実装するためにありますか
-
22-09-2019 - |
質問
次の方法で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) { ... }
BitWise XORオペレーターを使用できます(^
) 直接:
if (isEmptyString(firstStr) ^ isEmptyString(secondStr)) {
// ...
}
ブール以来、例で動作します true
と false
値はに変換されます 1
と 0
ビットワイズ演算子は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));
}
上記は、「排他的な分離」{どちらかではなく}の定義に由来します。
ブール値以来 true
と false
に変換されます 1
と 0
それぞれビットワイズ演算子を使用する場合、bitwise-xor ^
あなたの値がブール値である限り(JavaScriptの「Truthy」値が機能しない限り、論理XORとBitWiseOneとして二重勤務を行うことができます。これは否定で簡単に痛むことができます !
オペレーター。
a XOR b
次の(短い)式のリストと論理的に同等です。
!a ^ !b;
!a != !b;
可能な他の多くのフォームがあります - !a ? !!b : !b
- しかし、これらの2つのパターンには、評価するだけの利点があります a
と b
それぞれが一度(そして、「短絡」もしない場合は 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する必要がある場合はオプションのように見えます。
あなたはこれを行うことができます:
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;
}