November 14, 2019

A Scenario to Illustrate the Use of Array


The gallery has mounted an exhibition by one of its artists. Most of the show is devoted to paintings, but the artist has produced an edition of screen prints for the show. The gallery are always keen for this artist to produce and show prints as they know that sales will be good. Furthermore, they will continue to sell from the edition in the future. A couple of lines of code is enough to create and initialise the array to hold a record of the sales of the edition.

printSalesArray := Array new: 250.
1 to: (printSalesArray size) do: [:index | printSalesArray at: index put: 'unsold']

Thus all the elements are strings of value 'unsold'. Note that each string is a different object, but the value of each is the same.

There are other, easier, ways to implement this array.

printSalesArray atAllPut: 'unsold'


printSalesArray := Array new: 10 withAll: 'unsold'

Suppose that as each print is sold, the system executes the following:

printSalesArray at: (printSalesArray indexOf: 'unsold') put: 'sold'

The first element has 'sold' substituted in place of 'unsold' and so on. Here is an illustration of the array with the 10 elements prior to receiving the
indexOf: 'unsold' message.


1 2 3 4 5 6 7 8 9 10
'unsold' 'unsold' 'unsold' 'unsold' 'unsold' 'unsold' 'unsold' 'unsold' 'unsold' 'unsold'


Despite the fact that initially all the elements equal unsold', only the index of the first element in the array with the value 'unsold' is returned when the array receives the indexOf: 'unsold' message. Consequently, 1 is returned and forms the argument to at:. The expression evaluates to:

printSalesArray at: 1 put: 'sold'

1 2 3 4 5 6 7 8 9 10
'sold' 'unsold' 'unsold' 'unsold' 'unsold' 'unsold' 'unsold' 'unsold' 'unsold' 'unsold'


After the second sale

printSalesArray at: (printSalesArray indexOf: 'unsold') put: 'sold'

evaluates to

printArray at: 2 put: 'sold'

Each subsequent sale simply replaces the first element in the array equal to 'unsold' with 'sold'. If the gallery wish to find out how many prints from the edition have been sold, the following code will do the job. It declares the temporary variable count, initialises it to zero before iterating through the array, incrementing count each time an element equals the string 'sold'. Finally it returns count.

count := 0.
printSalesArray do: [:element| (element = 'sold')
                               ifTrue: [count := count + 1]].

Remember the do: method iterates over each element of the set and repeatedly sends the value: message to the block with the current element as the argument to value:. This means that we either have

[:element| (element = 'sold')
   ifTrue: [count := count + 1]]value: 'unsold'

in which case nothing happens, or

[:element| (element = 'sold')
   ifTrue: [count := count + 1]]value: 'sold'

in which case

(element = 'sold')

returns true, which in turn receives the message

ifTrue: [count := count + 1]

and count is incremented.

Finally there is one other message selector to consider.
Here the argument must be a block that employs two block arguments.

To further the scenario, a suite of 10 monotypes has been made by another artist and the gallery wish to record the sales. These prints are numbered from one to ten. Being monotypes, each print is different and consequently sales do not follow any particular order that matches the edition numbering.

monotypeSalesArray := Array new: 10

creates the array and the next line initialises all the elements to associations of print number and 'unsold'

1 to: (monotypeSalesArray size) do: [:index | monotypeSalesArray
             at: index put: (index ->'unsold')]

If, for example, the first print sold is the seventh of the series, the array can be updated with:

printSalesArray at: (printSalesArray indexOf: (7->'unsold'))
                                     put: (7->'sold')

If a buyer enquires on the availability of a print from the edition, the gallery might need to check which, if any, of the prints are left unsold. The following code will produce a dialogue box for each stored association where the value is 'unsold'.

monotypeSalesArray keysAndValuesDo: [:index :association |
                                      (association = (index ->'unsold'))
                                         ifTrue: [Dialog warn: 'Print  number ' ,index
                                                      printString,' is  unsold'.]]

In the above code the keysAndValuesDo: selector results in the block receiving a value:value: message selector with its two arguments being referenced by the block arguments index and association respectively. In other words, on each loop of the array, both the index and the stored association object, corresponding to that index, are accessed. Each of these values are placed in the code inside the block. The loop moves along the array, one index at a time, until all the stored elements have been accessed.

Next page » The protocol of String

Previous page « Array protocol
































































Up to top of page