Organizing Data

Do this on pencilcode.net

1. Make an array by [bracketing] some numbers joined by commas, and sum it up:

ages = [13, 5, 7, 2]
sum = 0
for n in ages
  sum += n
write 'sum is', sum
write 'average is', sum / ages.length

Arrays are sometimes called lists or vectors, and they represent a sequence of data.

The other fundamental data structure is an object. An object is similar to an array, except that it is enclosed by {curly braces}, and it gives a name to each value. Each named value is called a property. A object is sometimes called an map or a dictionary (because it maps keys like "alice" to values like 13).

2. Write the program averaging ages using a map instead of a list:

family = { alice: 13, bob: 5, cal: 7, dee: 2 }
sum = count = 0
for name, age of family
  write name, 'is', age
  sum += age
  count += 1
write 'sum is', sum
write 'average is', sum / count

In CoffeeScript, the word in is used to loop over a list, and the word of is used to loop over a map.

Names in a map can be quoted so that the name for each value can contain unusual characters like spaces or punctuation:

family = { "alice": 13, "mary-jane": 5, "j r": 5 }

3. Access single property of an object with a dot family.alice or with [brackets] family["j r"]:

family =
  alice: 13
  "mary-jane": 5
  "j r": 7
write 'alice is', family.alice
write 'j r is', family["j r"]
family.alice = 14
write 'now alice is', family.alice

In CoffeeScript, you will sometimes see maps written as a block of indented lines. When written this way, the curly braces can be omitted.

4. Arrays also use [brackets] for access. Acess the first element of an array with list[0], and access its last element with list[list.length - 1]:

list = [13, 5, 7]
write 'list has length', list.length
write 'first is', list[0]
write 'last is', list[list.length - 1]
list.push(2)
write 'now the last is', list[list.length - 1]
write 'list is', list.join('+')

The example also shows how to use list.push and list.join. Here is a quick summary of array techniques:

5. Arrays and objects can also contain other arays and objects. Try this:

group =
  alice:
    age: 13
    flavors: ['vanilla', 'chocolate']
  bob:
    age: 5
    flavors: ['strawberry', 'vanilla']
  cal:
    age: 7
    flavors: ['chocolate']
  dee:
    age: 2
    flavors: ['vanilla']
write "Bob's second favorite is", group.bob.flavors[1]
votes = {}
for name, info of group
  for flavor in info.flavors
    if flavor not of votes
      votes[flavor] = []
    votes[flavor].push info.age
    write info.age, 'year-old:', flavor
for flavor, ages of votes
  write 'ages for', flavor, ':', ages.join(',')

A couple tricky things here: votes = {} creates an empty object called "votes". Later on, if flavor not of votes checks if the votes object does not yet have a property for a flavor. If so, then votes[flavor] = [] sets the property to an empty array, and votes[flavor].push info.age adds a new age to the end of the array. In the end, votes is an object that has an array of ages for each flavor.