29.11.2014 Views

Smalltalk and Object Orientation: an Introduction - Free

Smalltalk and Object Orientation: an Introduction - Free

Smalltalk and Object Orientation: an Introduction - Free

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

11.9.3 The reject: message<br />

The reject: aBlock message evaluates aBlock for each element in the receiving collection. The<br />

result of this message is then a collection c ontaining the objects selected when aBlock evaluated to<br />

false. For example:<br />

(letters reject: [:each | each == $a] ) size<br />

This will return a collection containing all the elements in letters which weren’t the lower case ‘a’<br />

character. That is, this message returns all the elements in letters which fail the comparison test.<br />

11.9.4 The collect: message<br />

With the collect: aBlock message aBlock is again evaluated for each element in the receiving<br />

collection. The resulting returned collection object is the same size as the receiving collection. The<br />

returned collection contains the result of evaluating the block for each of the elements in the receiving<br />

collection. For example:<br />

(letters collect: [:each | each == $a] ) size<br />

This will return a collection of the same size as letters, with either true or false in each element<br />

depending on the outcome of the comparison.<br />

11.9.5 The detect: message<br />

In some cases we w<strong>an</strong>t to retrieve the first element in a collection which passes some test. The<br />

detect: aBlock message does this for us. It evaluates aBlock for each element in the receiving<br />

collection <strong><strong>an</strong>d</strong> <strong>an</strong>swers with the first element where aBlock evaluates to true. For example:<br />

letters detect: [:each | (each asUppercase == $A) |<br />

(each asUppercase == $B)]<br />

This c<strong>an</strong> be extremely useful if you have a collection of records <strong><strong>an</strong>d</strong> you need the first one which<br />

matches some test.<br />

11.10 Inserting into a collection<br />

The insert message is a very useful <strong><strong>an</strong>d</strong> very efficient operation. For example, if you have a collectio n<br />

of numbers which you wish to total you would either need to iterate over the collection using a do loop<br />

or convert the collection to <strong>an</strong> array <strong><strong>an</strong>d</strong> use <strong>an</strong> interval to mimic a Pascal style for loop.<br />

In <strong>Smalltalk</strong>, however, this type of operation (i.e. where you w<strong>an</strong>t to initialize some values <strong><strong>an</strong>d</strong> then<br />

perform the same thing on all elements in a collection) is so common that <strong>an</strong> extremely efficient<br />

construct is provided. This construct is called the inject: mech<strong>an</strong>ism. For example, assume you have<br />

a bag of integers <strong><strong>an</strong>d</strong> real numbers which you w<strong>an</strong>t to sum. You c<strong>an</strong> use inject: to do this, for<br />

example:<br />

| aBag result |<br />

aBag := Bag new.<br />

aBag add: 12; add: 24; add: 23.56; add: 7.<br />

result := aBag inject: 0 into: [:sum :item | sum + item ].<br />

This injects the initial value zero into sum <strong><strong>an</strong>d</strong> item. It then binds item to each of the elements of the bag<br />

in turn. Each time it does so, it adds item to the current value in sum <strong><strong>an</strong>d</strong> saves the result into sum. This<br />

is therefore equivalent to writing:<br />

| sum aBag |<br />

aBag := Bag new. sum := 0.<br />

aBag add: 12; add: 24; add: 23.56; add: 7.<br />

aBag do: [:item | sum := sum + item].<br />

result := sum.<br />

101

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!