-
-
Save gilzoide/6d7c435e4585f8ba96592f89f2442845 to your computer and use it in GitHub Desktop.
-- Returns false if value is falsey (`nil` or `false`), returns true if value is truthy (everything else) | |
function toboolean(v) | |
return v ~= nil and v ~= false | |
end | |
-- Returns true if one value is falsey and the other is truthy, returns false otherwise | |
function xor(a, b) | |
return toboolean(a) ~= toboolean(b) | |
end |
Oh, I guess you're right, thanks for the tip! In that case, I guess not a ~= not b
would also work and is a bit clearer to the reader.
Oops, wrote false
instead of true
above, fixed now. Also don't know why I thought nesting the not
outside was necessary as just inverting the equality is equivalent.
Unfortunately both the above and the not
approach fail on 0
and 1
since Lua considers both 'truthy' values. Anything outside of nil
and false
are truthy and therefor not 0
evaluates to false
. For anyone finding this gist on search engines like I did, for numbers use bit.bxor
instead from the standard library.
Unfortunately both the above and the not approach fail on 0 and 1 since Lua considers both 'truthy' values.
That's not failing, this is just how Lua behaves. I labeled this gist "logical xor" because it follows Lua's boolean logic, which is exactly what I needed at the time.
But it's easy enough to patch toboolean and have a version of xor that considers 0 as false, if anybody ever needs it:
function toboolean(v)
return v ~= nil and v ~= false and v ~= 0
end
function xor(a, b)
return toboolean(a) ~= toboolean(b)
end
It's also easy enough to inline the toboolean operation into xor as well, although I'd say that's a microoptimization and won't matter in most use cases.
The
not
keyword in Lua forcesnil
totrue
, meaning you can avoid the slower function overhead by doubling upnot
calls and inverting the equality. This should be as fast as you can possibly get it unless I'm mistaken: