6.2 Array Types

6.2.1 One-Dimensional Arrays

An array is an ordered list of variables. To get the idea, imagine a row of compartments, each of the compartments can contain something or be empty, and they are numbered sequentially starting at 0, as you see on the left side of Figure 6-1.

Arrays start counting their elements, or individual variables, at index 0, as the index is the offset from the beginning of the array. Index 0 is the position of the first element in any array that contains at least one element. Likewise, the n th element can be found at index n – 1. Starting at 0 and ending at n – 1 may seem odd, but it is common among most programming languages.

Diagram of an array and array access in Ruby
Figure 6-1. Diagram of an array and array access in Ruby

Gem of Wisdom

Array indices are the offset from the first element. As a result, the first element is stored at index 0.

The arrays in Figure 6-1 are known as one-dimensional arrays because there is only one index or dimension. To access an element in an array in Ruby, the notation is array_name[index], where array_name indicates the name of the array and index indicates the element of the array being referenced.

Consider an array named arr that stores a list of five test scores for a student. The student received the scores 73, 98, 86, 61, and 96. The first step of creating an array is the statement: array_name = Array.new. The example code in Example 6-1 shows how to initialize an array to store test scores.

Example 6-1. Initializing an array
    1 arr = Array.new()
    2 arr[0] = 73 
    3 arr[1] = 98 
    4 arr[2] = 86 
    5 arr[3] = 61 
    6 arr[4] = 96

The code shown is actual Ruby syntax for initializing array indices 0 through 4. The result of the code is much like the array in the righthand side of Figure 6-1, an array of size 5 with every element initialized. However, there is a quicker way to initialize an array, as shown in Example 6-2.

Example 6-2. Initializing an array
    1 arr = [73, 98, 86, 61, 96]

No matter which way the array is initialized, the result is the same. To use the array, you access array_name[index], as if it were a variable of the data type expected, as shown in Example 6-3.

Example 6-3. Changing the value of an element
    1 arr = [5,6]
    2 arr[0] = arr[0] + 10
    3 puts arr[0]

The key advantage of arrays is highlighted when used in conjunction with loops. Since the syntax for accessing an element in an array is array_name[index], we can use a variable for the index instead of literal numbers, as in the examples just shown. Thus, we can change the index in every loop iteration, and traverse or move through every element in the array. To know when to stop traversing the array, we can get the number of elements in an array by using the following statement:

arr.size

New programmers often make errors when dealing with the bounds of an array. These are the basic rules for array bounds:

  • The first element in an array is at index 0.

  • arr.size returns the number of elements in the array, not the highest indexed element.

  • The last element in an array is at index arr.size - 1.

If we want to use a while loop to traverse an array, we need to initialize the index to 0 and increment it for every loop iteration. It is important to note that the condition in the while loop is index < arr.size, not index <= arr.size, for the reasons just mentioned. The code in Example 6-4 is an example of basic array traversal that prints out every element in the array.

Gem of Wisdom

Using arrays is a flexible and organized way of expressing multiple related items. Every programming language has them. As an abstraction, arrays are expanded variables. A variable holds one value; an array holds many. For example, to record names of multiple institutions using variables requires the use of variables such as institution1, institution2, institution3, and so on. With arrays, institutions[] stores all institutions.

Example 6-4. Displaying array content
    1 arr = [73, 98, 86, 61, 96]
    2 index = 0
    3 while (index < arr.size)
    4 	puts arr[index]
    5 	index = index + 1
    6 end

Running the code (stored in a file called array_4.rb) gives the following output:

$ ruby array_4.rb
73
98
86
61
96

However, in Ruby it is possible to accomplish the same goal in one line of code:

puts arr

This example is meant to be merely an introduction to simple array traversal. More practical reasons to use loops and arrays together are illustrated later.

Example: Find the Max

The example in Example 6-5 shows how to find the maximum of a list of five non-negative numbers. What would you need to change to support negative numbers?

Example 6-5. Find the max
     1 # Initialize array and loop values
     2 arr = [73, 98, 86, 61, 96]
     3 index = 0
     4 max = 0
     5 
     6 # Loop over each element in arr
     7 while (index < arr.size)
     8 	if (arr[index] > max)
     9 		# Update max
    10 		max = arr[index]
    11 	end
    12 	index = index + 1
    13 end
    14 
    15 # Output calculated max
    16 puts "Max ==> " + max.to_s
  • Line 2 creates a new array named arr and initializes its variables.

  • Line 3 sets a counter named index that will serve as an index into the array.

  • Line 4 declares a variable called max that will be used to store the maximum number.

  • Lines 7–13 implement a loop that scans every element of the array.

  • Line 16 prints the maximum element at the end.

Each time the index variable index is incremented in line 12, the if statement in lines 8–11 tests to see whether the current value in the array indexed at index is higher than the current value in max. If the current value is higher, then the max variable is updated with the highest value.

Run this program, called find_the_max.rb. Your output should be:

$ ruby find_the_max.rb
Max ==> 98

As an exercise to make sure you understand the preceding code, change the example to output the lowest value in the array.

6.2.2 Multidimensional Arrays

Arrays that have more than one dimension are called multidimensional arrays. A common multidimensional array is the two-dimensional array, which can be used to represent matrices and coordinate systems. Unlike some other programming languages, Ruby does not provide built-in support for multidimensional arrays. The way to work around this is to put an array inside an array, which is essentially what a multidimensional array is anyway.

Consider the example in the previous section of an array that stores a list of five test scores for a student. Now, what if you had students with the following scores?

Geraldo: 73, 98, 86, 61, 96

Brittany: 60, 90, 96, 92, 77

Michael: 44, 50, 99, 65, 10

Table 6-1. Multidimensional array
 

[0]

[1]

[2]

[3]

[4]

[0]

73

98

86

61

96

[1]

60

90

96

92

77

[2]

44

50

99

65

10

The best way to represent this data is to create one array with three indices and to have each index contain five elements. This is basically an array with three rows and five columns. To create such an array in Ruby, type in the following:

arr = [[73, 98, 86, 61, 96],
       [60, 90, 96, 92, 77],
       [44, 50, 99, 65, 10]]

By typing in this assignment statement, you have created a 3  × 5 table where the first, second, and third rows represent Geraldo’s, Brittany’s, and Michael’s test scores, respectively. To access an individual score, use the format array[row][column]. So, if you wanted to know what Brittany scored on her third exam (remember, each index starts with 0, not 1), type:

puts "Brittany's Third Exam: " + arr[1][2].to_s

The output should be:

Brittany's Third Exam: 96

The rules for traversing a multidimensional array are similar to traversing a one-dimensional array, except you have to add a nested loop for each extra dimension. In Example 6-6, we illustrate how to print out each value in the array arr.

Example 6-6. Outputting multidimensional arrays
     1 # Initialize array and loop values
     2 arr = [[73, 98, 86, 61, 96], 
     3        [60, 90, 96, 92, 77], 
     4        [44, 50, 99, 65, 10]] 
     5 row = 0
     6 column = 0
     7 
     8 # Loop over each row
     9 while (row < arr.size)
    10 	puts "Row: " + row.to_s
    11 	# Loop over each column
    12 	while (column < arr[row].size)
    13 		# Print the item at position row x column
    14 		puts arr[row][column]
    15 		column = column + 1
    16 	end
    17 	# Reset column, advance row
    18 	column = 0
    19 	row = row + 1
    20 end

Gem of Wisdom

Step through Example 6-6 and convince yourself that it generates the values you expect. What output values will be generated? What would happen if we added an if statement after line 13 that asked to skip values that were prime? Give that a try, as it uses our prime number work.

Like one-dimensional arrays, you can output everything using one line of code:

puts arr

The only problem with this statement is that Ruby will list all the values without any formatting. So it would be difficult to sort through all the data. We address means to format output in one particular case as part of our tic-tac-toe example in Chapter 12. We do not address formatting generally in this book.

Example: Find the Max—Modified

In the previous example, we created a program that finds the highest score in the array. Now we will create a program that stores the five scores for all three students. Using what you learned previously, modify the program to find out which student has the highest score. Print out the highest score.

When you are done with your program, compare your program to the code in Example 6-7.

Example 6-7. Find the max, modified
     1 # initialize the array and index/score variables
     2 arr = [[73, 98, 86, 61, 96], 
     3        [60, 90, 96, 92, 77], 
     4        [44, 50, 99, 65, 10]] 
     5 
     6 row = 0
     7 column = 0
     8 maxscore = 0
     9 maxrow = 0
    10 
    11 # for each row
    12 while (row < arr.size)
    13    # for each column
    14    while (column < arr[row].size)
    15       # update score variables
    16       if (arr[row][column] > maxscore)
    17          maxrow = row
    18          maxscore = arr[row][column]
    19       end
    20       # increment column
    21       column = column + 1
    22    end
    23    # reset column, increment row
    24    column = 0
    25    row = row + 1
    26 end
    27 
    28 # output name and high score information
    29 if maxrow == 0
    30    puts "Geraldo has the highest score."
    31 elsif maxrow == 1
    32    puts "Brittany has the highest score."
    33 elsif maxrow == 2
    34    puts "Michael has the highest score."
    35 else
    36    puts "Something didn't work correctly."
    37 end
    38 puts "The high score was: " + maxscore.to_s
  • Lines 2–4 initialize a 3  × 5 array called arr.

  • Lines 6–7 initialize the initial location of the row and column to start traversing the array.

  • Lines 8–9 declare maxscore that will keep track of the highest score and maxrow that will keep track of who has the highest score.

  • Lines 12–26 implement a loop that scans each element of the array.

  • Lines 29–37 compare the value of maxrow and output the corresponding person’s name as the individual with the highest score.

  • Line 38 outputs the highest score.

Intuitively, like the previous example, there is a marker for the highest score. Whenever the program finds a score higher than the current value of maxscore, it updates maxrow to contain the value of the row in which the program found the high score (line 17) and maxscore to reflect the highest score (line 18). The program then uses if-else statements to find out who has the highest score (lines 29–37). Notice again how rows 0, 1, and 2 correspond with Geraldo, Brittany, and Michael, respectively. When you run the program, the output should read:

$ ruby find_the_max_modified.rb
Michael has the highest score.
The high score was: 99
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.237.24