Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save bga/1993712 to your computer and use it in GitHub Desktop.

Select an option

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

bga commented Mar 7, 2012

Copy link
Copy Markdown
Author
({
  '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

bga commented Mar 7, 2012

Copy link
Copy Markdown
Author
(
  (
    [
      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
      function() {
        ret = c
      }
    ][parseInt(String(a)[1], 16)] 
  )
  || function() {
    ret = b
  }
)() 

@bga

bga commented Mar 7, 2012

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

@FGRibreau

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

@naholyr

naholyr commented Mar 7, 2012

Copy link
Copy Markdown

@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

naholyr commented Mar 7, 2012

Copy link
Copy Markdown
[b, c][2+~a]

@naholyr

naholyr commented Mar 7, 2012

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

@Amatewasu

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

@bga

bga commented Mar 7, 2012

Copy link
Copy Markdown
Author

@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

bga commented Mar 7, 2012

Copy link
Copy Markdown
Author

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

@jneira

jneira commented Mar 7, 2012

Copy link
Copy Markdown
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

jneira commented Mar 7, 2012

Copy link
Copy Markdown

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
Copy Markdown

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

dtipson commented Mar 9, 2012

Copy link
Copy Markdown

[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

padolsey commented Mar 9, 2012

Copy link
Copy Markdown

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
Copy Markdown

@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

zachleat commented Mar 9, 2012

Copy link
Copy Markdown

I believe

[c, b][a]

should be

[c, b][+a]

Edit: Damn you mathias! :)

@vrs

vrs commented Mar 12, 2012

Copy link
Copy Markdown

@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

jneira commented Mar 13, 2012

Copy link
Copy Markdown

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