In which we list tips, tricks, and reminders.
Links to official docs:
Helper methods for testing and whatnot.
{print, ok, eq, arrayEq} = require 'tester'List method names of arrays and strings:
dir = (obj) -> Object.getOwnPropertyNames(obj.constructor.prototype)
print dir [] # last, extend, pop, push, ...
print dir 's' # upper, length, lower, ...A few numbers for stuff below.
nums = [1..4]Print each value:
print x for x in nums # 1 2 3 4Print index, value pairs:
print i, x for x, i in numsPrint key, value pairs of object:
numbers =
one: 1
two: 2
three: 3
print key, value for key, value of numbersFilter out even values:
isEven = (x) -> x % 2 == 0
arrayEq [1, 3],
(x for x in nums when not isEven x)Generate list of squares:
square = (x) -> Math.pow(x, 2)
arrayEq [1, 4, 9, 16],
nums.map squareEquivalent to ...
arrayEq [1, 4, 9, 16],
(square x for x in nums)Generate list of squares for values in object:
numbers =
one: 1
two: 2
three: 3
arrayEq [1, 4, 9],
(square x for word, x of numbers)A simple counter:
class Counter
constructor: (@total=0) ->
inc: (n=1) -> @total += ncounter = (total=0) ->
(inc=1) -> total += inccount = new Counter(5)
eq count.inc(), 6
eq count.inc(), 7
eq count.total, 7Split a string:
words = "foo bar baz biz buz".split(" ")
arrayEq words, ['foo', 'bar', 'baz', 'biz', 'buz']
words = "foo|bar|baz|biz|buz".split("|")
arrayEq words, ['foo', 'bar', 'baz', 'biz', 'buz']Extend prototype w/ pythonic method names
String::upper = -> @toUpperCase()
String::lower = -> @toLowerCase()
eq 'FOO', 'foo'.upper()
eq 'foo', 'FOO'.lower()wordlist = "foo bar baz biz buz".split(" ")
ok 'foo' in wordlist
ok not ('boo' in wordlist)Make a dict (associative array) for easy lookups:
dict = {}
for word in wordlist
dict[word] = 1
ok dict['foo'] and not dict['boo']
ok dict.foo and not dict.booPass in a string of words for easy lookups:
makeDict = (wordlist) ->
new class then constructor: ->
@[word] = 1 for word in wordlist.split(" ")
dict = makeDict "foo bar baz biz buz"
ok dict['foo'] and not dict['boo']
ok dict.foo and not dict.booVariant version:
class Dict
constructor: (wordlist) ->
@[word] = 1 for word in wordlist.split(" ")
dict = new Dict "foo bar baz biz buz"
ok dict['foo'] and not dict['boo']
ok dict.foo and not dict.booFilter out non-dict words:
sent = "I want to foo that bar with biz"
dictwords = (word for word in sent.split(" ") when dict[word])
arrayEq dictwords, ['foo', 'bar', 'biz']
We'll use this list of numbers below.
nums = [1..4]Get length of array:
eq 4, nums.lengthPop last element: x = nums.pop() arrayEq nums, [1..3]
Push element to end and return length:
n = nums.push(x)
arrayEq nums, [1..4]
eq nums.length, nReverse order:
arrayEq nums.reverse(), [4..1]Sort elements:
arrayEq nums.sort(), [1..4]Shift (pop off first element):
x = nums.shift()
arrayEq nums, [2..4]Unshift (push element to front and return length):
n = nums.unshift(x)
arrayEq nums, [1..4]
eq n, 4Lexicographic sort (default):
nums = [9, 10, 100, 20, 200, 3, 1]
arrayEq nums.sort(), [1, 10, 100, 20, 200, 3, 9]Numeric sort:
numeric = (a, b) -> a - b
arrayEq nums.sort(numeric), [1, 3, 9, 10, 20, 100, 200]Splice first element:
nums = [1..10]
x = nums.splice(0, 1) # same as nums.pop()
arrayEq nums, [2..10]
arrayEq x, [1]Splice first two elements:
nums = [1..10]
x = nums.splice(0, 2)
arrayEq nums, [3..10]
arrayEq x, [1, 2]Splice out second element:
nums = [1..10]
x = nums.splice(1, 1)
expected = [1].concat [3..10]
arrayEq nums, expected
arrayEq x, [2]Splice out second and third elements:
nums = [1..10]
arrayEq nums.splice(1, 2), [2, 3]
arrayEq nums, [1].concat [4..10]Note the syntax: array.splice(index, count)
Splice in elements at start of array (index 0):
nums = [1..4]
nums.splice(0, 0, 'a', 'b')
arrayEq nums, ['a', 'b'].concat [1..4]Replace two elements at start of array (index 0):
nums = [1..4]
nums.splice(0, 2, 'a', 'b')
arrayEq nums, ['a', 'b', 3, 4]Note the syntax: array.splice(index, count, a, b, ...)
nums = [1..4]
nums.splice(0, 2, 'a', 'b', 'c')
arrayEq nums, ['a', 'b', 'c', 3, 4]Concatenate:
arrayEq [1..10],
[1..5].concat [6..10]
arrayEq [1..10],
[1..5].concat 6, 7, 8, 9, 10Join list elements into a string:
eq '1,2,3,4', [1..4].join()
eq '1|2|3|4', [1..4].join('|')
eq '1234', [1..4].join('')Sum values in a list:
nums = [1..4]
eq 10, nums.reduce (x, y) -> x + yTest for some true elements:
some = (list, fn) ->
for e in list
return yes if fn e
no
gtThree = (x) -> x > 3
gtFour = (x) -> x > 4
ok some nums, gtThree
ok not some nums, gtFourTest that all elements are true:
all = (list, fn) ->
for e in list
return no unless fn e
yes
ltFive = (x) -> x < 5
ok not all nums, gtThree
ok not all nums, gtFour
ok all nums, ltFive
It can be handy to define custom array methods on the Array
prototype so they can be used like the reduce method above.
Sum array of numbers:
Array::sum = (x, y) -> @.reduce (x, y) -> x + y
eq 10, nums.sum()Get the last item:
Array::last = -> @[@.length - 1]
eq 4, nums.last()Trim out all falsy values from an array:
Array::compact = ->
item for item in @ when item
arrayEq [1, 2, 3],
[1, false, 2, '', 3, null].compact()Flatten a nested array:
Array::flatten = ->
flat = []
for e in @
if Array.isArray e
flat = flat.concat e.flatten()
else
flat.push e
flat
arrayEq [1..4],
[1, [2, [3, [4]]]].flatten()Extend an array (as mutator method):
Array::extend = (other) ->
Array::push.apply @, other
@
letters = ['a', 'b', 'c']
letters.extend ['d', 'e', 'f']
eq letters.length, 6
eq letters.last(), 'f'Collect the doubled value for each number in nums:
nums = [1..4]
doubles = []
double = (x) -> doubles.push (x * 2)
nums.forEach double
arrayEq doubles, [2, 4, 6, 8]Every element meets condition?
ok doubles.every (x) -> x > 1
ok not doubles.every (x) -> x < 4Some elements meet condition?
ok doubles.some (x) -> x < 4
ok not doubles.some (x) -> x > 50Filter out elements not meeting condition:
arrayEq [3, 4], nums.filter (x) -> x > 2Map a function to each element:
arrayEq [2..5], nums.map (x) -> x + 1Reduce elements to a single value:
eq 10, nums.reduce (x, y) -> x + yFind min/max in a list:
nums = [10, -10, 100, 0, 1]
eq 100, Math.max.apply @, nums
eq -10, Math.min.apply @, numsPrimality tester:
isPrime = (x) ->
p = 2
while p * p <= x
return false if x % p == 0
p += 1
trueFind primes:
arrayEq [1, 2, 3, 5, 7, 11, 13, 17, 19],
(x for x in [1..20] when isPrime x)Find factors:
factors = (n) -> i for i in [1..n] when n % i == 0
arrayEq [1, 11],
factors 11