Return to lecture notes index
February 5, 2008 (Lecture 7)

Exam Reminder

We've got an exam next class. It focuses in on Perl, including today's coverage of associative arrays, and shell scripting. for the most part, you will be asked to write code, not to interprete it. And, the most interesting parts to us are those aspects of Perl and shell that are unique -- the features that make the languages special. We'll also look out for the small details that are unique -- different types of quotes and brackets, for example. With respect to shell, you'll need to know some of the tools of the trade, including grep, sed, tr, bc, expr, &c. And, regular expressions will be a big deal. I might ask you to use them with sed or grep, and/or I might ask you to write them to match some data, or ask you which strings would be recognized by a particular regex. With respect to regex, please don't forget about ()-grouping and \x-registers.

Associative Arrays

Perl has a really cool language feature called Associative Arrays. Associative arrays are like regular arrays, except that they allow the use of strings as keys. So, when storing a value into an array, we don't need to use a numerical index -- we can use something descriptive. They are called "associative" arrays, because they they associate the key and the value, as contrasted with traditional arrays which associate a value with a somewhat arbitrary, and certainly less descriptive, numerical index. For example, consider an array of bank balances:

  $bankbalance{"Greg"} = 100.00;
  $bankbalance{"Amy"} = 150.00;

  $mybalance = $bankbalance{"Greg"};
  

We see that the keys are strings: "Greg" and "Amy". We see that the associative array, in effect, pairs them with their values, 100.00 and 150.00, respectively.

For those of you who happen by chance to be familiar with hash tables, it is easy to see that they are the natural implementation for associative arrays. The string key is hashed and, the resulting hash, is used as the numerical index into an array. Fot those of you who are not presently familiar with hash tables, no worries -- we'll talk about them soon enough.

A "Middle Spectrum" Language Feature

Associative arrays are tremendously useful to programmers. They are useful anytime we want effectively constant time, immediate, access to a value via some key. But, we tend not to see them as a language feature in scripting languages or in compiled high-level languages. Instead, they are generally available as a language feature in the languages in the "middle" of the spectrum from scripting languages to compiled languages, languages such as Perl, Python, AWK, &c.

Associative arrays are a type of complex data structure. And, we tend not to see real data structures in scripting languages -- they are hard to share with the programs that do the real work. Instead, we tend to use the file system to store information that can't be held in scalar variabels or arrays in memory. The idea is that we generally pipe data into and out of programs that are capable of building their own complex data structures.

Unlike traditional arrays, which are easily projected into memory, associative arrays really are complex data structures. So, instead of hiding this complexity behind normally simple operators, compiled languages generally leave it to libraries, such as C++'s STL or Java's Collections classes.

Unlike scripting languages, the languages in the "middle" of our language spectrum have a different model. Rather than stringing together external programs to solve problems, they make very heavy use of their own data strcutres and complex libraries. But, unliked compiled languages which have some concern about efficiency, "middle spectrum" languages are more concerned about convenience than efficiency.

As such, they are more than willing to hide the complexity of associative arrays from the programmer within a first-class language feature since it makes programming more efficient. The fact is that the average Perl programmer would rather have associative arrays and not care about the implementation than to have to make use of a library for a very commonly used feature.

Syntax Detail

Recall that, in Perl, scalar variables begin with a $-dollar sign and traditional arrays begin with an @-sign. Associative arrays begin with a %-percent sign. As with traditional arrays, when referencing an individual element of an associative array, a $-dollar sign is used. As with traditional arrays, the reason is simple -- a single element of an array is a scalar value, not an array.

Instead of using []-brackets to identify individual elements, associative arrays use {}-squiggles. Take a look a second look at our prior exmple to see the basic use cases: setting and getting the value of an element:

  $bankbalances{"Greg"} = 100.00;
  $bankbalances{"Amy"} = 150.00;

  $mybalance = $bankbalances{"Greg"};
  

Initializing an Associative Array

An associative array can be initialized as a whole. To do this, we just feed it a list of key-value pairs. The individual pairs are just run together:

  %bankbalance = { "Greg", 100.00, "Amy", 150.00};
  

It is very important to notice that the key-value pairs are grouped together by their relative position within the initializer list. As a consequence, if we want to have an empty value, we can't just leave it out completely -- we need to save the place using an empty position within the list. Notice that "Greg" has no value -- but we still preserved its space within the list. Having discussed this syntax, I'd also like to observe that it is a much better to set some initial value, any initial value, than to leave it out. At least that way, you'll know where you are starting.

  %bankbalance = { "Greg", , "Amy", 150.00};
  

Iterating Through Associative Arrays

It is possible to itertate through an associative array using a foreach loop just as it is a traditional array. Notice the addition of the keys or values keyword. This controls if the iteration traverses the keys or the values.

  for each $client in (keys %bankbalances) {
    print "Client: $client\n";
  }

  for each $amount in (values %bankbalances) {
    print "Amount: $amount\n";
  }

  # We can look up the value given the key so that we cna, in effect,
  # iterate through  tuples
  for each $client in (keys %bankbalances) {
    print "$client: $bankbalances{$client}\n";
  }
  

Some Other Fun Stuff

It is possible to assign associative arrays to traaditional arrays and vice-versa. When converting from a traditional array into an associative array, it groups the elements into key-value pair by assuming that they alternate, e.g., key1, value1, key2, value2, key3, value3, ...keyN, valueN. When an associative array is assigned into a traditional array, the traditional array will be organized the same way, as a list of alternating keys and values. If an associative array is assigned to a traditional array and then back, there is no guarantee that, if it is again converted to a traditional array that the pairs will be in the same order. As you'll learn when we talk about hash tables, because of "collision", the order of insertion can affect the organization.

  @flatbankbalances = %bankbalances;
  %bankbalances = @bankbalances;