无论如何,在JavaScript中实现XOR吗
-
22-09-2019 - |
题
我正在尝试通过以下方式在JavaScript中实现XOR:
// XOR validation
if ((isEmptyString(firstStr) && !isEmptyString(secondStr)) ||
(!isEmptyString(firstStr) && isEmptyString(secondStr))
{
alert(SOME_VALIDATION_MSG);
return;
}
在JavaScript中有更好的方法吗?
谢谢。
解决方案
我假装您正在寻找逻辑XOR,因为JavaScript已经有一个(^):)
我通常使用一个简单的三元操作员(我使用的极少数时间之一):
if ((isEmptyString(firstStr) ? !isEmptyString(secondStr)
: isEmptyString(secondStr))) {
alert(SOME_VALIDATION_MSG);
return;
}
编辑:
在@Jeff肉丸上工作 解决方案
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))) {
// ...
}
更容易的方法:
if ((x+y) % 2) {
//statement
}
假设两个变量都是真正的布尔人,也就是说 1
或者 0
.
- 如果
x === y
你会得到一个偶数的数字,所以XOR将会0
. - 而如果
x !== y
那你会得到一个奇数,所以xor将会1
:)
第二个选项,如果您注意到 x != y
评估为XOR,然后您要做的就是
if (x != y) {
//statement
}
它将再次评估为XOR。 (我更喜欢这一点)
当然,一个好主意是将其实施到一个函数中,但这只是您的选择。
希望这两种方法中的任何一种能帮助某人!我将此答案标记为社区Wiki,因此可以改进。
查看 这个 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只是表示“这两个布尔值有不同吗?”。所以:
if (!!isEmptyString(firstStr) != !!isEmptyString(secondStr)) {
// ...
}
这 !!
S只是为了保证 !=
操作员比较了两个真正的布尔值,因为可以想象 isEmptyString()
返回其他东西(例如 null
对于false或字符串本身为true)。
假设您正在寻找布尔XOR,这是一个简单的实现。
function xor(expr1, expr2){
return ((expr1 || expr2) && !(expr1 && expr2));
}
上面源自“独家分离”的定义{一个,但不是两者}。
由于布尔值 true
和 false
转换为 1
和 0
分别在其上使用位运算符时,位于位XOR ^
只要您的值是布尔值(JavaScript的“真实”值无法正常工作),只要您的值是逻辑XOR和BITWEESTONE,就可以将双重功能作为逻辑XOR和BITWEWSONE。否定很容易获得 !
操作员。
a XOR b
逻辑上等同于以下(简短)表达式列表:
!a ^ !b;
!a != !b;
还有很多其他形式 - 例如 !a ? !!b : !b
- 但是这两种模式具有仅评估的优势 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操作员,因此您的构造似乎是合理的。如果是数字,那么您可以使用 ^ ie位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;
}
我希望这将是最短,最干净的
function xor(x,y){return true==(x!==y);}
这将适用于任何类型
这是一个XOR函数,该函数采用可变数量的参数(包括两个)。这些论点只需要真实或虚假,而不是 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上,它在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
}
有几种方法,但是三元方法(a?!b:b)似乎表现最好。另外,如果您经常需要Xor事物,则设置boolean.prototype.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;
}