私は次のようにJavaScriptでXORを実装しようとしています:
// XOR validation
if ((isEmptyString(firstStr) && !isEmptyString(secondStr)) ||
(!isEmptyString(firstStr) && isEmptyString(secondStr))
{
alert(SOME_VALIDATION_MSG);
return;
}
これをJavaScriptで行うより良い方法はありますか?
ありがとう。
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演算子を適用します。たぶん、最初の解決策ほどメンテナンスが難しいかもしれません(または私は最初の解決策に慣れすぎているかもしれません)
他の人が指摘したように、論理XORはブール値の等しくないと同じなので、これを行うことができます:
// XOR validation
if( isEmptyString(firstStr) != isEmptyString(secondStr) )
{
alert(SOME_VALIDATION_MSG);
return;
}
XORブール値のビット値を簡単にモデル化できるXOR(Javascriptが持つ))を実行しています:
var a = isEmptyString(firstStr) ? 1 : 0;
var b = isEmptyString(secondStr) ? 1 : 0;
if(a ^ b) { ... }
ビット単位のXOR演算子(^
)を直接使用できます。
if (isEmptyString(firstStr) ^ isEmptyString(secondStr)) {
// ...
}
ブール値true
とfalse
の値は1
と0
に変換されるため、ビットワイズ演算子は32ビット整数で動作するため、これは例として機能します。
その式は0
または1
も返し、その値はif
ステートメントによってブール値に強制的に戻されます。
上記のアプローチで発生する型強制に注意する必要があります。優れたパフォーマンスを求めている場合は、ビット演算子を使用することはお勧めしません。ブール論理のみを使用して簡単な関数を作成することもできます。演算子:
function xor(x, y) {
return (x || y) && !(x && y);
}
if (xor(isEmptyString(firstStr), isEmptyString(secondStr))) {
// ...
}
より簡単な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つの方法のいずれかが誰かを助けることを願っています!私はこの回答をコミュニティウィキとしてマークしているので、改善することができます。
チェックアウト 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;
}
this 記事からの引用:
残念ながら、JavaScriptには論理XOR演算子がありません。
XOR演算子の動作を次のようなもので「エミュレート」できます。
if( !foo != !bar ) {
...
}
リンクされた記事では、いくつかの代替アプローチについて説明しています。
ブール値true
およびfalse
は、ビット単位演算子を使用すると、それぞれ_1
_および_0
_に変換されるため、ビット単位XOR _^
_は、論理値としての二重義務XORと同様に、値がブール値である限り(Javascriptの「真の」値は機能しません)これは否定__!
_演算子。
_a XOR b
_は、式の次の(短い)リストと論理的に同等です。
_!a ^ !b;
!a != !b;
_
_!a ? !!b : !b
_など、他にも多くの形式が考えられますが、これらの2つのパターンには、a
とb
をそれぞれ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 ) ) { ... }
_
XORは、「これらの2つのブール値は異なるのか」という意味です。したがって:
if (!!isEmptyString(firstStr) != !!isEmptyString(secondStr)) {
// ...
}
!!
sは、!=
演算子が2つの真のブール値を比較することを保証するためのものです。おそらく、isEmptyString()
は何か他のものを返します(falseの場合はnull
、trueの場合は文字列自体)。
BOOLEAN XORを探していると仮定して、簡単な実装を次に示します。
function xor(expr1, expr2){
return ((expr1 || expr2) && !(expr1 && expr2));
}
上記は、「排他的選言」{どちらか一方、両方ではない}の定義から派生しています。
Javascriptには論理的なXOR演算子がないため、構成が妥当であるように思われます。それが数値であった場合、^つまりビット単位XOR演算子を使用できます。
乾杯
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;
}
これが最も短くてきれいなものになることを願っています
function xor(x,y){return true==(x!==y);}
これはどのタイプでも機能します
@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;
}
これを試してください:function xor(x,y) var result = x || y if (x === y) { result = false } return result }
いくつかの方法がありますが、3種類の方法(a?!b:b)が最も効果的です。また、頻繁にXORする必要がある場合は、Boolean.prototype.xorの設定がオプションのように見えます。
あなたはこれを行うことができます:
Math.abs( isEmptyString(firstStr) - isEmptyString(secondStr) )
その結果は、XOR演算の結果です。
以下は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;
}