我正试图通过以下方式在javascript中实现XOR:
// XOR validation
if ((isEmptyString(firstStr) && !isEmptyString(secondStr)) ||
(!isEmptyString(firstStr) && isEmptyString(secondStr))
{
alert(SOME_VALIDATION_MSG);
return;
}
在javascript中有更好的方法吗?
感谢。
答案 0 :(得分:55)
正如其他人所指出的那样,逻辑XOR与布尔值不相等,所以你可以这样做:
// XOR validation
if( isEmptyString(firstStr) != isEmptyString(secondStr) )
{
alert(SOME_VALIDATION_MSG);
return;
}
答案 1 :(得分:34)
我假装你正在寻找一个逻辑XOR,因为javascript已经有一个按位(^):)
我通常使用一个简单的三元运算符(我很少使用其中一个):
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运算符。也许它不像第一个解决方案那么可维护(或者我可能已经习惯了第一个解决方案)
答案 2 :(得分:11)
你正在做一个布尔值的XOR,很容易建模成一个按位XOR(Javascript有):
var a = isEmptyString(firstStr) ? 1 : 0;
var b = isEmptyString(secondStr) ? 1 : 0;
if(a ^ b) { ... }
答案 3 :(得分:8)
您可以直接使用按位XOR运算符(^
):
if (isEmptyString(firstStr) ^ isEmptyString(secondStr)) {
// ...
}
它将适用于您的示例,因为布尔true
和false
值转换为1
和0
,因为按位运算符使用32位整数。 / p>
该表达式也将返回0
或1
,并且该值将通过if
语句强制回布尔值。
你应该知道上面的方法发生的类型强制,如果你正在寻找良好的性能,我不建议你使用按位运算符,你也可以使用一个简单的函数来做到这一点只有布尔逻辑运算符:
function xor(x, y) {
return (x || y) && !(x && y);
}
if (xor(isEmptyString(firstStr), isEmptyString(secondStr))) {
// ...
}
答案 4 :(得分:7)
更容易的一种方法:
if ((x+y) % 2) {
//statement
}
当然假设两个变量都是真正的布尔值,即1
或0
。
x === y
您将获得偶数,那么XOR将为0
。x !== y
那么你会得到一个奇数,那么XOR将是1
:)第二个选项,如果您注意到x != y
评估为异或,那么您必须做的就是
if (x != y) {
//statement
}
这将再次评估为异或。 (我更喜欢这个)
当然,一个好主意是将它实现到一个函数中,但它只是你的选择。
希望这两种方法中的任何一种都可以帮到某人!我将此答案标记为社区维基,因此可以对其进行改进。
答案 5 :(得分:5)
引自this文章:
不幸的是,JavaScript没有逻辑XOR运算符。
您可以通过以下方式“模拟”XOR运算符的行为:
if( !foo != !bar ) {
...
}
链接的文章讨论了几种替代方法。
答案 6 :(得分:5)
结帐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;
}
答案 7 :(得分:2)
XOR只是意味着“这两个布尔值是不同的吗?”。因此:
if (!!isEmptyString(firstStr) != !!isEmptyString(secondStr)) {
// ...
}
!!
只是为了保证!=
运算符比较两个真正的布尔值,因为可以想象isEmptyString()
返回其他内容(如null
表示false,或者字符串本身为真)。
答案 8 :(得分:2)
由于布尔值true
和false
在使用按位运算符时分别转换为1
和0
,因此按位-XOR ^
可以只要您的值是布尔值(Javascript的“truthy”值不起作用),可以将双重任务作为逻辑XOR和bitwiseone进行操作。使用否定!
运算符很容易实现。
a XOR b
在逻辑上等同于以下(短)表达式列表:
!a ^ !b;
!a != !b;
还有许多其他形式可能 - 例如!a ? !!b : !b
- 但这两种模式的优点是每次只评估a
和b
(并且不会“短路” “如果a
为假,因此未评估b
),那么使用三元?:
,OR ||
或AND &&
运算符的表单将会加倍评估或短路。
两个语句中的否定!
运算符非常重要,原因如下:它将所有“truthy”值转换为布尔值(“” - > false,12 - > true等)因此,按位运算符具有可以使用的值,因此不等式!=
运算符仅比较每个表达式的真值(如果a != b
或a
b
,则!!a ^ !!b
将无法正常工作非相等,非空字符串等),以便每个评估返回一个布尔值结果而不是第一个“真实”值。
您可以通过添加双重否定(或异常,2(a + b) == 2a + 2b
,仍然等效于XOR)继续扩展这些表单,但在否定表达式的一部分时要小心。如果你在算术中考虑分布(!( a ^ b )
!( !!a ^ !!b )
!!a == !!b
等),这些形式似乎乍一看“工作”,但实际上从XOR(these produce similar results to logical NXOR)产生不同的真值表:
function xor( a, b ) { return !a ^ !b; }
然后,XOR的一般形式可能是函数(truth table fiddle):
if ( xor( isEmptyString( firstStr ), isEmptyString( secondStr ) ) ) { ... }
然后你的具体例子是:
isEmptyString
或者,如果xor
仅返回布尔值,而您不想使用通用if ( isEmptyString( firstStr ) ^ isEmptyString( secondStr ) ) { ... }
函数,则只需:
{{1}}
答案 9 :(得分:2)
假设您正在寻找BOOLEAN XOR,这是一个简单的实现。
function xor(expr1, expr2){
return ((expr1 || expr2) && !(expr1 && expr2));
}
上述内容源于“独占分离”的定义{{one one,but not both}}。
答案 10 :(得分:1)
Javascript没有逻辑XOR运算符,因此您的构造似乎是合理的。如果它是数字,那么你可以使用^即按位XOR运算符。
欢呼声
答案 11 :(得分:1)
这是一个可以容纳两个到多个参数的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;
}
答案 12 :(得分:1)
我希望这将是最短最干净的
function xor(x,y){return true==(x!==y);}
这适用于任何类型
答案 13 :(得分:0)
@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;
}
答案 14 :(得分:0)
你可以这样做:
Math.abs( isEmptyString(firstStr) - isEmptyString(secondStr) )
结果是XOR操作的结果。
答案 15 :(得分:0)
有几种方法,但三元方法(a?!b:b)似乎表现最佳。此外,如果您需要经常使用xor,设置Boolean.prototype.xor似乎是一个选项。
答案 16 :(得分:0)
试试这个:
function xor(x,y)
var result = x || y
if (x === y) {
result = false
}
return result
}
答案 17 :(得分:0)
这是一个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;
}