// add your variants of | |
a ? b : c | |
// in comments :) | |
// a is boolean | |
// b and c - any type | |
// lazy evaluation isnt important |
bga
commented
Mar 7, 2012
(
(
[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
function() {
ret = c
}
][parseInt(String(a)[1], 16)]
)
|| function() {
ret = b
}
)()
[c, b][parseInt(!a, 011 << 2) >> 0xDEADBEAF >> 011]
({116: b, 102: c})[String(a).charCodeAt(0)]
a << 2 && b || c
@bga a && Object(b) || Object(c)
won't work if b or c are scalar (amongst other cases).
as a && b || c
wouldn't work either if b is falsey:
(a && [b] || [c])[0]
[b, c][2+~a]
Boolean.prototype.ternary = function (b, c) { /* WARNING INCEPTION DETECTED */ return this ? b : c }
→ a.ternary(b, c)
(a * 2 == a && c || d)[0]
@naholyr Object wrapper to make 0, empty string and false non falsey
true && 0 || 1 // 1
true && Object(0) || 1 // 0
Of course it has issue - Object(null) <=> {}
@naholyr but your fix (wrap into array) is better
var IFTHENELSE=function (x) { return function(y) { return function(z) {return x(y(z))}}}
var a=function(x) {return function(y) {return x}}
var result=IFTHENELSE(a)(function(_) {return "b"})(function(_){return "c"})()
console.log(result)
// b
The previous version was wrong. it works with true(=a) but no with false. The new one works and... look! it requires another ternary operator
var IFTHENELSE=function (x) { return function(y) { return function(z) {return (x(y))(z)}}}
var TRUE=function(x) {return function(y) {return x}}
var FALSE=function(x) {return function(y) {return y}}
function ternary (a,b,c) {return IFTHENELSE(a?TRUE:FALSE)(function(_) {return b})(function(_){return c})()}
console.log(ternary("a","b","c"))
// b
console.log(ternary(false,"b","c"))
//c
To easily test these in your console, run this line:
var a = true, b = 'a is true', c = 'a is false';
Then copy-paste any snippet from this page to check if it works correctly. Try setting a = false
too!
({t:b,f:c})[(''+a).charAt()]
…or, in slightly more readable form:
({ 't': b, 'f': c })[String(a).charAt()]
({'':b,e:c})[(''+a).slice(4)]
…or, in slightly more readable form:
({ '': b, 'e': c})[String(a).slice(4)]
({ true: b, false: c })[String.fromCharCode(a) != '\0']
({ true: b, false: c })[a['\x76\x61\x6c\x75\x65\x4f\x66']('\x70\x72\x6f\x62\x6c\x65\x6d\x3f')]
({ true: b, false: c })[Boolean((+a).toExponential().indexOf('0'))]
…or, with some extra mindfuck:
[c, b][(+(+a)['\x74o\x45x\x70o\x6ee\x6e\x74i\x61l']('H̹̙̦̮͉̩̗̗ͧ̇̏̊̾Eͨ͆͒̆ͮ̃͏̷̮̣̫̤̣ ̵̞̹̻̀̉̓ͬ͑͡ͅCͯ̂͐͏̨̛͔̦̟͈̻O̜͎͍͙͚̬̝̣̽ͮ͐͗̀ͤ̍̀͢M̴̡̲̭͍͇̼̟̯̦̉̒͠Ḛ̛̙̞̪̗ͥͤͩ̾͑̔͐ͅṮ̴̷̷̗̼͍̿̿̓̽͐H̙̙̔̄͜')[0])]
[c, b][a] doesn't work for me: it returns undefined, which seems expected. But [c, b][ ~ ~ a] works for true/false/1/0 and [c, b][!! ~ ~ a] works for negative numbers (at least if you expect them to resolve to true).
Shouldn't this:
[c, b][a]
Be this: (?)
[c, b][+!!a]
Or:
[b,c][+!a]
IMHO, this is the most readable ternary operation:
Array(2).concat(b, c)[String(a).match(/(t)|(f)/).join().split(',,').push(1)]
@padolsey It could simply be [c, b][+a]
, as the gist states that a
is a boolean (not just a truthy/falsy value). But yeah, [c, b][a]
doesn’t look right.
I believe
[c, b][a]
should be
[c, b][+a]
Edit: Damn you mathias! :)
@jneira I love that lambda calculus inspired version. How about this? (Credits to you, this is just sugar)
var lambdas = {
true: function(x) {return function(y) {return x}},
false: function(x) {return function(y) {return y}},
ifthenelse: function (x) { return function(y) { return function(z) {return (x(y))(z)}}}
}
function ternary (a,b,c) {
return lambdas.ifthenelse(lambdas[!!a])(function(_) {return b})(function(_){return c})()
}
console.log(ternary("a","b","c"))
// b
console.log(ternary(false,"b","c"))
//c
better, but credits to Alonzo Church!, we are simple mortals