Skip to content

Instantly share code, notes, and snippets.

@autotelicum
Created August 19, 2011 01:24
Show Gist options
  • Save autotelicum/1155779 to your computer and use it in GitHub Desktop.
Save autotelicum/1155779 to your computer and use it in GitHub Desktop.
How do you add 's' to a word when there is more than one of something?
# How do you add 's' to a word when there is more than one of something?
# It is often seen in JavaScript to use the ternary operator but that is coding
# like it was PHP at the expense of future maintenance and internationalization.
# Only case 2 handles negative numbers.
show = console.log # console.debug # alert
test = (points) ->
# Readable
#----------
# The simple, readable way
show "0: You got #{points} point#{if points > 1 then 's' else ''}"
# Encapsulate in a function, future i18n will be easier
pluralIf = (stem, cond) -> stem + (if cond then 's' else '')
show "1: You got #{points} #{pluralIf 'point', points > 1}"
# Encapsulate in a function, handle negative numbers
pluralUnless = (stem, cond) -> stem + (unless cond then 's' else '')
show "2: You got #{points} #{pluralUnless 'point', -2 < points < 2}"
# Encapsulate in a String method, could collide with another definition
String::pluralIf ?= (cond) -> this + (if cond then 's' else '')
show "3: You got #{points} #{'point'.pluralIf points > 1}"
# Tricks
#--------
# Use the existential operator to catch the singular undefined
show "4: You got #{points} point#{('s' if points > 1) ? ''}"
# Convert the condition to a number and do an array lookup
show "5: You got #{points} point#{['','s'][+(points > 1)]}"
# Use the inverted condition to ask for a letter
# (true => charAt 1 => '') (false => charAt 0 => 's')
show "6: You got #{points} point#{'s'.charAt points <= 1}"
# Create an array whose length is determined by the condition
# It consists of empty elements so join it with 's'
show "7: You got #{points} point#{Array(1+(points>1)).join 's'}"
# Concatenate to an empty array, undefined does nothing
show "8: You got #{points} point#{[].concat ('s' if points > 1)}"
# Test
#------
test n for n in [-3..3]
@satyr
Copy link

satyr commented Aug 19, 2011

show "9: You got #{points} point#{['s' if points > 1]}"

Related: jashkenas/coffeescript#1406

@autotelicum
Copy link
Author

Satyr, your number 9 is very cool! Looking at the code and searching through ECMA-262 does not even make it clear to me that it would work that way - but it does! Learning something new is as good as it gets, thanks.

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