Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bga/1993712 to your computer and use it in GitHub Desktop.
Save bga/1993712 to your computer and use it in GitHub Desktop.
[fun] various forms of ternary operator in JavaScript
// add your variants of
a ? b : c
// in comments :)
// a is boolean
// b and c - any type
// lazy evaluation isnt important
@bga
Copy link
Author

bga commented Mar 7, 2012

({
  'true': b, 
  'false': c
})[a]
[c, b][a]
[0 ,1 ,2 ,3 , b, c][String(a).length]
a && Object(b) || Object(c)
switch(a) {
  case true: return b
  case false: return c
}
if(a) {
  return b
}
else {
  return c
}
(String(a)
  .replace('true', function() {
    ret = b
  })
  .replace('false', function() {
    ret = c
  })
)

@bga
Copy link
Author

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
  }
)() 

@bga
Copy link
Author

bga commented Mar 7, 2012

[c, b][parseInt(!a, 011 << 2) >> 0xDEADBEAF >> 011]

@FGRibreau
Copy link

({116: b, 102: c})[String(a).charCodeAt(0)]
a << 2 && b || c

@naholyr
Copy link

naholyr commented Mar 7, 2012

@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]

@naholyr
Copy link

naholyr commented Mar 7, 2012

[b, c][2+~a]

@naholyr
Copy link

naholyr commented Mar 7, 2012

Boolean.prototype.ternary = function (b, c) { /* WARNING INCEPTION DETECTED */ return this ? b : c }
 a.ternary(b, c)

@Amatewasu
Copy link

(a * 2 == a && c || d)[0]

@bga
Copy link
Author

bga commented Mar 7, 2012

@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) <=> {}

@bga
Copy link
Author

bga commented Mar 7, 2012

@naholyr but your fix (wrap into array) is better

@jneira
Copy link

jneira commented Mar 7, 2012

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

@jneira
Copy link

jneira commented Mar 7, 2012

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

@mathiasbynens
Copy link

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])]

@dtipson
Copy link

dtipson commented Mar 9, 2012

[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).

@padolsey
Copy link

padolsey commented Mar 9, 2012

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)]

@mathiasbynens
Copy link

@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.

@zachleat
Copy link

zachleat commented Mar 9, 2012

I believe

[c, b][a]

should be

[c, b][+a]

Edit: Damn you mathias! :)

@vrs
Copy link

vrs commented Mar 12, 2012

@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

@jneira
Copy link

jneira commented Mar 13, 2012

better, but credits to Alonzo Church!, we are simple mortals

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment