简体   繁体   中英

Print a SortedCollection to screen using keysAndValueDo (smalltalk)

您好,我正在学习并且是Smalltalk的新手,我正在尝试将我的SortedCollection打印到屏幕上以尝试使用keysAndValueDo,但我不确定这样做如何,如果有人可以给我一个通用的例子,那会很好

The following example works with Pharo Smalltalk, other Smalltalk implementation might work similar.

  1. First, look at existing print methods as examples. In case of SortedCollection , you find them in the printing protocol of its superclass Collection .

  2. You will find that the printing of elements is defined in printElementsOn: . So you could overwrite this method in SortedCollection .

Here is a printElementsOn: method that will use keysAndValuesDo: , as you were asking for:

printElementsOn: aStream
    aStream nextPut: $(.
    self keysAndValuesDo: [:key :value | 
        aStream
            nextPut: $(;
            print: key;
            nextPut: $:;
            space;
            print: value;
            nextPut: $)].
    aStream nextPut: $)

Now a collection that before printed:

"a SortedCollection(1 2 3 3 5 10)"

will print:

"a SortedCollection((1: 1)(2: 2)(3: 3)(4: 3)(5: 5)(6: 10))"

Part 1 - Displaying to the screen
The most straight forward way to print to the screen in a GUI-based Smalltalk is to use the message:
Transcript show: 'some text'
(The Transcript is a system object that displays into a scrollable window).

To make sure there is a newline before each line of display text, we send the message cr to the Transcript

Transcript cr.
Transcript show: 'some text'.

A shorthand method, that saves us re-typing Transcript over and over, is to send Transcript a series of messages one after another. This is called a message cascade . Each time we end a message in ; it means send to the same receiver as the last message was sent to .

We can then shorten this again, as Smalltalk pays no attention to newlines in expressions.

The final display message cascade becomes:
Transcript cr; show: 'some text'.

Part 2: Enumerating aSortedCollection using keysAndValuesDo: This keyword message is SequencableCollectionand its method header is:
keysAndValuesDo: aBlock "Enumerate the receiver with all the keys (aka indices) and values."

(It works the same way in Dolphin, and in Squeak and its derivatives, Pharo and Cuis).

The keyword message keysAndValuesDo: takes a block argument.
A block is an anonymous object, with one method. Its method is defined between a matched pair of square brackets - a [ ... ] pair.

In this case, we need a local variable in the block for the key of each element of the collection, and another local variable for the value of each element.

We can call them anything we like, and in this case, it is the order that they appear in that is important. keysAndValuesDo: will put the element's key into the first local variable in the block, and will put the element's value into the second local variable in the block.

Local variables in a block are declared at the start of the block, and each variable name is identified by prefixing it with : . The local variable declarations are ended with a | .

The block then looks like
[:local1 :local2 | "do something for each element, with the key in local1 and the value in local2" ]

I prefer meaningful local variable names, so I'll use eachKey and eachValue .

Part 3: Putting it all together
To enumerate through mySortedCollection

"Declare the mySortedCollection variable"
|mySortedCollection| 

"Initialise the collection"
mySortedCollection := SortedCollection new.  

"add in some data to the collection"
mySortedCollection add: ('First') ;
                   add: ('Second') ;
                   add: ('Third').

"Enumerate through the collection, displaying to the Transcript window"
mySortedCollection keysAndValuesDo: 
   [:eachKey :eachValue | 
    Transcript cr; show: eachKey; show: ' '; show: eachValue
] .

Paste the code into a Workspace (known as a Playground in Pharo, from version 4.0 onwards). Select the text. Once selected, right-click (on a two or three button mouse) and select "Do it" from the menu. Or use Ctrl-d as a keyboard shortcut. (The exact chording key may vary on your platform)

Final notes
In a SortedCollection or an OrderedCollection, the key is the index. The value is what is stored at element[index].

In a Dictionary, the key of the element is the key, and the value of the element is the value.

SortedCollections are sorted in order of the element values, according to the definition of the collections sort block . In the absence of a custom sort block, they will be added in ascending order. 'First' , 'Second' and 'Third' are, coincidentally, in alphabetical order. It happens to work out nicely in this example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM