Associative Arrays
Associative arrays use scalar values as subscripts, which means you can have a word represent the index value. Perl uses the percent sign (%) to distinguish an associative array from an ordinary array variable.
Referring to Associative array elements | $fruit{"bananas"} = 1; Note: using the dollar sign ($) tells the perl interpreter that this is a single scalar item and is to be treated as such |
Creating an associative array | %associative_array; # declare an associative array $fruit{"bananas"} = 1; Note: There is no order within the array, elements can be all over the place |
Copying associative arrays from array variables | @fruit = (apples", 6, "cherries", 8, "oranges", 11); %fruit = @fruit; |
Adding an element | $fruit{"bananas"} = 1; |
Deleting an element | delete($fruit{"bananas"}); Note: delete is the only way to delete from an associative array |
Listing the keys | %array = ("foo", "26", "bar", "27"); # keys is commonly used as below Note: in no particular order will the list be returned |
Listing the values | %array = ("foo", "26", "bar", "27"); @values = values(%array); print("@values\n"); foreach $i (values (%array)) { Note: in no particular order will the list be returned |
Looping an associative array | %valle = ("Paul", 35, "Lorraine", "31", "Dominic", 12, "Jessica", 8); ## Using the foreach loop # Using a while loop Note: do not use delete when using each, because the behavior of each unpredictable |
For more on manipulating arrays see List Manipulation.
Data Structures
You can use associative arrays to simulate a wide variety of data structures found in high-level languages, you could implement the following data structures
Linked Lists
A Linked List is a simple data structure that enables you to store items in a particular order. Each element of the linked list contains two fields
Linked List structure | %words = ("alpha", "bravo", "bravo", "Charlie", "Charlie", "delta", "delta", ""); $header = "alpha" |
Complete Linked List Example | # initialize list to empty $header = ""; while ($line = <STDIN>) { # remove leading and trailing spaces $line =~ s/^\s+|\s+$//g; @words = split(/\s+/, $line); foreach $word (@words) { # remove closing punctuation, if any $word =~ s/[.,;:-]$//; # convert all words to lower case $word =~ tr/A-Z/a-z/; &add_word_to_list($word); } } &print_list; sub add_word_to_list { # if list is empty, add first item # if word identical to first element in list, do nothing # see whether word should be the new first word in the list # find place where word belongs # if word already seen, do nothing sub print_list { print ("Words in this file:\n"); |
Structures
Many programming languages enable you to define collections of data called structures. Like Lists, structures are collections of values, each element of a structure, however, has its own name and can be accessed by that name.
Simulate a structure | # C Structure # Perl Simulated structure |
Trees
A tree is similar to a linked list, except that each element of a tree points to more than one other element. The simplest example of a tree is a binary tree. Each element of a binary tree, called a node, points to two other elements, called the left child and right child. Each of these children points to two children of its own and so on, the very last node are called leaf nodes.
The following terminology is used when describing trees
Tree Example | $rootname = "parent"; %tree = ("parentleft", "child1", "parentright", "child2", "child1left", "grandchild1", "child1right", "grandchild2", "child2left", "grandchild3", "child2right", "grandchild4"); # traverse tree, printing its elements &print_tree($rootname); sub print_tree { $leftchildname = $nodename . "left"; |
Databases
Using the above methods you can build quite complex databases, associative arrays can use variable records lengths, are accessible either sequentially or randomly.
The below calculator example is a very complex script, it uses associative arrays and recursive subroutines and the tree structure.
Calculator Example:
To run the calculator program | $calculator Should result in 16 |
very complex example |
# statements which initialize the program $nextnodenum = 1; # initialize node name generator &get_next_item; # read first value from file $treeroot = &build_expr; $result = &get_result ($treeroot); print ("the result is $result\n"); # Build an expression. sub build_expr { local ($currnode, $leftchild, $rightchild); local ($operator); $leftchild = &build_add_operand; if (&is_next_item("+") || &is_next_item("-")) { $operator = &get_next_item; $rightchild = &build_expr; $currnode = &get_new_node ($operator, $leftchild, $rightchild); } else { $currnode = $leftchild; } } # Build an operand for a + or - operator. sub build_add_operand { local ($currnode, $leftchild, $rightchild); local ($operator); $leftchild = &build_mult_operand; if (&is_next_item("*") || &is_next_item("/")) { $operator = &get_next_item; $rightchild = &build_add_operand; $currnode = &get_new_node ($operator, $leftchild, $rightchild); } else { $currnode = $leftchild; } } # Build an operand for the * or / operator. sub build_mult_operand { local ($currnode); if (&is_next_item("(")) { # handle parentheses &get_next_item; # get rid of "(" $currnode = &build_expr; if (! &is_next_item(")")) { die ("Invalid expression"); } &get_next_item; # get rid of ")" } else { $currnode = &get_new_node(&get_next_item, "", ""); } $currnode; # ensure correct return value } # Check whether the last item read matches # a particular operator. sub is_next_item { local ($expected) = @_; $curritem eq $expected; } # Return the last item read; read another item. sub get_next_item { local ($retitem); $retitem = $curritem; $curritem = &read_item; $retitem; } # This routine actually handles reading from the standard # input file. sub read_item { local ($line); if ($curritem eq "EOF") { # we are already at end of file; do nothing return; } while ($wordsread == @words) { $line = |