﻿1
00:00:00,960 --> 00:00:05,160
In this course,
we'll study the essential elements

2
00:00:05,320 --> 00:00:07,600
of the collections hierarchy in Pharo.

3
00:00:07,760 --> 00:00:11,760
We'll see that Pharo
has many types of collections.

4
00:00:11,920 --> 00:00:14,960
They make a programmer's life easier

5
00:00:15,120 --> 00:00:17,360
as they all share the same API.

6
00:00:17,520 --> 00:00:22,720
We'll also see the difference
between literal and dynamic collections.

7
00:00:23,960 --> 00:00:28,720
The collections' API is very diverse:
there are many types of collections.

8
00:00:28,880 --> 00:00:32,360
They all share a common API
which is well organized

9
00:00:32,520 --> 00:00:34,880
and make a programmer's life easier.

10
00:00:35,440 --> 00:00:37,880
What's specific about Pharo

11
00:00:38,040 --> 00:00:41,000
is that the first element is at index 1

12
00:00:41,160 --> 00:00:43,560
instead of 0 in other languages.

13
00:00:44,280 --> 00:00:47,880
Collections can contain
any types of objects in Pharo.

14
00:00:48,040 --> 00:00:50,840
It's not always the case
with other languages.

15
00:00:51,440 --> 00:00:55,240
Let's see some of the most remarkable
and widely used collections:

16
00:00:55,400 --> 00:00:57,960
OrderedCollection
is a dynamic collection

17
00:00:58,120 --> 00:01:02,160
which grows
whenever you add elements in it.

18
00:01:02,320 --> 00:01:05,560
Array is a collection of fixed size.

19
00:01:05,720 --> 00:01:09,200
You can access the elements
according to an index, Set,

20
00:01:09,360 --> 00:01:13,280
which contains elements
without duplicates.

21
00:01:13,440 --> 00:01:16,200
You can't insert the same element twice.

22
00:01:16,360 --> 00:01:21,160
Dictionaries are hash tables:
to one key is associated one value.

23
00:01:22,040 --> 00:01:24,840
This is an excerpt
of the collection hierarchy.

24
00:01:25,000 --> 00:01:28,160
It's only an excerpt:
in Pharo, it's bigger.

25
00:01:28,320 --> 00:01:31,240
There are many classes.
They all have collections

26
00:01:31,400 --> 00:01:34,120
with a shared API
for all the collections.

27
00:01:34,880 --> 00:01:39,160
In this course, I'll tell you
about those in bold type.

28
00:01:40,480 --> 00:01:44,240
There's a shared API
with seven elements:

29
00:01:44,400 --> 00:01:49,240
specific methods for the creation
of collections sent to the classes;

30
00:01:49,400 --> 00:01:52,120
specific methods
to access their properties

31
00:01:52,280 --> 00:01:54,840
(the size of the collections

32
00:01:55,000 --> 00:01:57,840
or even the elements they contain);

33
00:01:58,000 --> 00:02:00,920
testing methods
(is the collection empty?);

34
00:02:01,080 --> 00:02:05,320
elements adding and removing methods;
collection elements enumeration

35
00:02:05,480 --> 00:02:11,400
(I want to browse the elements
or know whether an element is there);

36
00:02:11,560 --> 00:02:15,920
and conversion methods
from one type to another.

37
00:02:16,760 --> 00:02:20,640
Let's start with an example:
I want to create a collection in Pharo.

38
00:02:20,800 --> 00:02:24,120
I'll just select
the class I'm interested in

39
00:02:24,280 --> 00:02:28,040
and send the message new
to instantiate this class.

40
00:02:28,200 --> 00:02:30,360
First option: I use new.

41
00:02:30,520 --> 00:02:33,720
Second option: I can't use new directly.

42
00:02:33,880 --> 00:02:36,360
I want to specify the size
of the collection.

43
00:02:36,520 --> 00:02:41,440
I could send new: 4.
I create a size-4 or size-2 array.

44
00:02:41,600 --> 00:02:45,720
It also work with OrderedCollection.
I could create one of size 1000.

45
00:02:47,400 --> 00:02:51,920
There are other existing methods
to create pre-initialized collections:

46
00:02:52,080 --> 00:02:53,520
withAll: for instance.

47
00:02:53,680 --> 00:02:58,360
I'll pass a literal collection.
A literal collection starts with #(.

48
00:02:59,120 --> 00:03:02,480
I'll create a new instance
of OrderedCollection

49
00:03:02,640 --> 00:03:06,760
which will contain all the elements
passed when it was created.

50
00:03:07,600 --> 00:03:09,360
I could do the same with Set.

51
00:03:09,520 --> 00:03:12,760
In a set, you can't have any duplicates.

52
00:03:12,920 --> 00:03:16,640
The number 7, which you have twice
in the literal collection,

53
00:03:16,800 --> 00:03:19,000
can't end up twice in Set.

54
00:03:21,200 --> 00:03:25,680
There are other types of messages
you can send

55
00:03:25,840 --> 00:03:27,920
to the classes to initialize them.

56
00:03:28,080 --> 00:03:31,600
This is another example: new: withAll:.

57
00:03:31,760 --> 00:03:33,880
I want a size-5 collection.

58
00:03:34,040 --> 00:03:37,360
Every element must be initialized
with a specific object:

59
00:03:37,520 --> 00:03:40,000
in this case, a string containing a.

60
00:03:42,240 --> 00:03:46,400
Remember that in Pharo,
every collection starts at index 1.

61
00:03:46,560 --> 00:03:49,480
If I ask this 3-element collection

62
00:03:49,640 --> 00:03:53,440
to return the element at index 2,
it'll be this one.

63
00:03:53,600 --> 00:03:56,000
This is 1; this is 2; this is 3.

64
00:03:56,760 --> 00:03:58,960
It's the same with OrderedCollection:

65
00:03:59,120 --> 00:04:02,480
If I convert this collection
and ask it to return its index 2,

66
00:04:02,640 --> 00:04:04,560
I'll get the same result: hates.

67
00:04:05,840 --> 00:04:09,960
Collections can contain
any types of objects.

68
00:04:10,120 --> 00:04:12,280
I'll show you one example:

69
00:04:12,440 --> 00:04:16,920
this literal collection
contains the string calvin

70
00:04:17,080 --> 00:04:22,000
and a collection
containing the numbers 1 2 3.

71
00:04:22,160 --> 00:04:23,960
I can create an array.

72
00:04:24,120 --> 00:04:28,360
This array is composed
of the elements 1 2

73
00:04:29,360 --> 00:04:32,600
and of Set at the end.

74
00:04:33,360 --> 00:04:37,160
I added the element 1 here,
then the element 2, then Set.

75
00:04:37,920 --> 00:04:41,160
You can browse
the elements of a collection

76
00:04:41,320 --> 00:04:43,800
by using the message do: for instance.

77
00:04:44,600 --> 00:04:46,400
This is a collection

78
00:04:47,400 --> 00:04:51,080
to which I'll send the message do:
before passing it a block.

79
00:04:51,720 --> 00:04:56,920
The block starts with "["
and ends with "]".

80
00:04:57,080 --> 00:05:00,720
The block's parameter is called :each.

81
00:05:00,880 --> 00:05:03,240
It is separated
from the block's body by |.

82
00:05:03,400 --> 00:05:07,200
With each loop, the value of :each
is the collection's 1st element,

83
00:05:07,360 --> 00:05:08,800
then the second, etc.

84
00:05:08,960 --> 00:05:12,440
And on the transcript you have:
Calvin hates Suzie.

85
00:05:14,480 --> 00:05:18,120
Arrays are fixed-size collections.

86
00:05:18,280 --> 00:05:22,280
You can query an array for its size:
I send the message size.

87
00:05:22,440 --> 00:05:26,440
You can directly access an array's
element by sending at:.

88
00:05:26,600 --> 00:05:28,120
I want the second element.

89
00:05:28,280 --> 00:05:31,640
You can modify the element
at index 2 in the collection

90
00:05:31,800 --> 00:05:35,160
by sending at: 1 put: 'Calvin':

91
00:05:35,680 --> 00:05:38,400
I insert the string Calvin
in cell 1.

92
00:05:39,160 --> 00:05:41,040
I can also ask the size.

93
00:05:41,200 --> 00:05:44,600
What's interesting about this example

94
00:05:44,760 --> 00:05:47,800
is that the same array
has been built in two ways:

95
00:05:47,960 --> 00:05:51,720
first a literal version,
then a dynamic version.

96
00:05:51,880 --> 00:05:56,360
Here, I instantiated
the class Array by myself

97
00:05:56,520 --> 00:05:58,120
and filled in every cell.

98
00:05:59,440 --> 00:06:03,200
You can send size to a collection
to learn about its size.

99
00:06:03,360 --> 00:06:07,600
You can access a collection's element
by using the method at:.

100
00:06:07,760 --> 00:06:09,200
I already mentioned it.

101
00:06:10,480 --> 00:06:12,480
Be careful:

102
00:06:12,640 --> 00:06:16,000
when you access an element
by providing an index,

103
00:06:16,160 --> 00:06:18,400
you must ensure that the index

104
00:06:18,560 --> 00:06:23,400
is within the collection's bounds:
it should be smaller than its size.

105
00:06:23,560 --> 00:06:27,720
If I ask this collection to return
the element at index 55, it won't exist.

106
00:06:27,880 --> 00:06:30,400
It'll return an error.

107
00:06:33,360 --> 00:06:35,480
To modify the elements:

108
00:06:35,640 --> 00:06:40,120
at index 2, I want to insert
a new element in the collection.

109
00:06:40,280 --> 00:06:43,960
The string loves
will replace the string hates.

110
00:06:44,120 --> 00:06:46,200
You can see it in the result.

111
00:06:48,800 --> 00:06:52,080
Literal arrays:

112
00:06:52,240 --> 00:06:55,400
this is an example of a literal array.

113
00:06:55,560 --> 00:06:57,840
It starts with #(, as I told you.

114
00:06:58,000 --> 00:07:01,520
You can put anything inside:
a number, a string, etc.

115
00:07:02,360 --> 00:07:05,160
Every literal array in Pharo

116
00:07:05,320 --> 00:07:07,840
are instance of the class Array
by default.

117
00:07:08,000 --> 00:07:10,960
I can send the message class
to a literal array.

118
00:07:11,120 --> 00:07:14,920
It returns Array, which means
it's instance of the class Array.

119
00:07:18,800 --> 00:07:22,400
Dynamic and literal versions
are equivalent in Pharo.

120
00:07:22,560 --> 00:07:26,440
Literal arrays are simply shorter:
you can write them faster.

121
00:07:26,600 --> 00:07:29,760
Here you have a collection's
literal version.

122
00:07:29,920 --> 00:07:33,760
And that's the dynamic version
where I instantiate the class Array.

123
00:07:33,920 --> 00:07:37,240
They're equivalent
as they return the same results.

124
00:07:40,000 --> 00:07:43,560
The class OrderedCollection
defines a specific collection

125
00:07:43,720 --> 00:07:45,600
which can be extended.

126
00:07:45,760 --> 00:07:48,640
Whenever you add elements, it grows.

127
00:07:49,280 --> 00:07:53,320
I instantiate OrderedCollection
by sending the message new.

128
00:07:53,480 --> 00:07:57,040
I use the method add: to add
new elements in this collection.

129
00:07:57,200 --> 00:08:01,280
I could use addFirst: to add an element
at the beginning of the collection.

130
00:08:01,440 --> 00:08:03,080
By default, it's at the end.

131
00:08:04,400 --> 00:08:07,600
You can see what the collection returns.

132
00:08:07,760 --> 00:08:11,440
It is composed of three elements:
Pharo, Reef, Pharo.

133
00:08:11,600 --> 00:08:15,400
With add: 'Seaside',
'Seaside' is added at the end.

134
00:08:17,760 --> 00:08:21,520
I have conversion methods
between a collection type and another.

135
00:08:21,680 --> 00:08:26,160
Here I'm using a literal collection,
which is an array.

136
00:08:26,320 --> 00:08:30,440
The message asOrderedCollection
will turn this array

137
00:08:30,600 --> 00:08:32,600
into an ordered collection.

138
00:08:33,520 --> 00:08:37,200
Sets are a type of collection
without duplicates.

139
00:08:37,360 --> 00:08:41,600
They can be extended:
they grow with every added element.

140
00:08:41,760 --> 00:08:45,560
I can use a literal collection
I turn into a Set.

141
00:08:45,720 --> 00:08:49,080
I end up with a Set
without any duplicates.

142
00:08:49,880 --> 00:08:53,400
I could also choose the dynamic version
over the literal one:

143
00:08:53,560 --> 00:08:57,720
Set with: with: creates a Set
and fills it with two elements,

144
00:08:57,880 --> 00:08:59,440
that's two Sets each time.

145
00:09:02,000 --> 00:09:06,640
Conversion methods are convenient to
turn a collection into something else.

146
00:09:06,800 --> 00:09:11,280
It's always the same: as + the name
of the collection you want to get.

147
00:09:13,840 --> 00:09:17,000
Dictionaries are a group
of collections key/values:

148
00:09:17,160 --> 00:09:19,280
I associate a value to a key.

149
00:09:19,440 --> 00:09:22,760
They can be extended:
they grow with every added element.

150
00:09:22,920 --> 00:09:25,560
There's also an unusual API

151
00:09:25,720 --> 00:09:28,360
when it comes to this collection:

152
00:09:28,520 --> 00:09:32,120
typical at: message; at:ifabsent:

153
00:09:32,280 --> 00:09:37,200
(what do I return if I want to access
a specific key that doesn't exist?);

154
00:09:37,360 --> 00:09:42,160
at:put: insert a new value
into a specific key.

155
00:09:42,320 --> 00:09:47,520
I can iterate using typical messages
such as do:,

156
00:09:47,680 --> 00:09:49,080
but also new messages

157
00:09:49,240 --> 00:09:52,640
such as keysDo: which browses
all the dictionary's keys

158
00:09:52,800 --> 00:09:54,280
or keys and values.

159
00:09:54,440 --> 00:09:58,240
For instance, I create an instance
of the class Dictionary.

160
00:09:59,040 --> 00:10:03,360
Picture the Dictionary as an array:

161
00:10:03,520 --> 00:10:08,040
to the key January, I associate 31;
to the key February, 28;

162
00:10:08,200 --> 00:10:10,160
to the key March, 31.

163
00:10:12,840 --> 00:10:16,280
It's equivalent to a dynamic collection.

164
00:10:16,440 --> 00:10:21,480
You create a dynamic collection using {:

165
00:10:21,640 --> 00:10:23,720
{ and }.

166
00:10:23,880 --> 00:10:26,640
You use arrows to create associations.

167
00:10:26,800 --> 00:10:29,000
This is a symbol.

168
00:10:29,160 --> 00:10:33,080
To the symbol January
I associate the number 31.

169
00:10:33,240 --> 00:10:35,720
I have a collection of associations

170
00:10:35,880 --> 00:10:38,440
I turn into a dictionary
with asDictionary.

171
00:10:38,600 --> 00:10:42,840
These two ways of creating a dictionary
are equivalent.

172
00:10:45,480 --> 00:10:48,280
If I query association for its key,

173
00:10:48,440 --> 00:10:50,760
it will return the key,
so the beginning.

174
00:10:50,920 --> 00:10:52,400
It's the same.

175
00:10:52,560 --> 00:10:56,400
If I query an association for its value,
it'll only return the value.

176
00:10:56,560 --> 00:10:58,760
This is a pair or an association.

177
00:11:00,560 --> 00:11:01,760
Dictionaries:

178
00:11:01,920 --> 00:11:06,080
if I want to access a specific value
in a Dictionary,

179
00:11:06,240 --> 00:11:11,600
I just need to use at: and to specify
the key whose value I want.

180
00:11:11,760 --> 00:11:13,800
If the key doesn't exist,

181
00:11:14,360 --> 00:11:17,720
I will get an error in return.

182
00:11:18,560 --> 00:11:23,000
To avoid that,
I can use at: ifAbsent:.

183
00:11:23,160 --> 00:11:26,600
I write at: plus a key
that doesn't exist in the Dictionary.

184
00:11:26,760 --> 00:11:30,720
If it is absent,
it will return this value, 0.

185
00:11:31,480 --> 00:11:35,040
The key doesn't exist in the Dictionary,
so I get the value 0.

186
00:11:35,200 --> 00:11:40,480
I can iterate over a Dictionary:
if use do: over its elements,

187
00:11:40,640 --> 00:11:45,280
I get the Dictionary's values only.
You can't see the keys.

188
00:11:45,440 --> 00:11:48,800
One might wonder why
as it's quite strange.

189
00:11:48,960 --> 00:11:50,720
It's very logical, actually.

190
00:11:50,880 --> 00:11:55,560
If you look at the way do:, taking
a block, is implemented in Dictionary,

191
00:11:55,720 --> 00:11:58,760
what happens is ^self valuesDo:.

192
00:11:58,920 --> 00:12:01,480
By default, if you apply do:
to a Dictionary,

193
00:12:01,640 --> 00:12:04,080
you only browse its values,
not the keys.

194
00:12:05,440 --> 00:12:07,040
If I want to browse both,

195
00:12:07,200 --> 00:12:10,680
I must use a specific method
called keysAndValuesDo:

196
00:12:10,840 --> 00:12:15,120
which takes a block with two arguments
(:k and :v) as parameter.

197
00:12:15,280 --> 00:12:18,680
:k is a key
and v: is the value.

198
00:12:19,360 --> 00:12:22,160
The Dictionary is full.

199
00:12:23,880 --> 00:12:26,720
In this course, we learned that

200
00:12:26,880 --> 00:12:30,520
Pharo has plenty of different types
of collections available.

201
00:12:31,160 --> 00:12:33,800
The collections have a common vocabulary

202
00:12:33,960 --> 00:12:35,720
when it comes to creating them,

203
00:12:35,880 --> 00:12:38,760
accessing their elements,
their size, etc.

204
00:12:38,920 --> 00:12:41,080
It makes a programmer's life easier.

205
00:12:41,240 --> 00:12:44,560
It's easy to convert a collection
into another type.

206
00:12:44,720 --> 00:12:46,600
We even learned something more:

207
00:12:46,760 --> 00:12:50,800
when you have questions, it's easy
to look into the system, into Pharo,

208
00:12:50,960 --> 00:12:54,960
by reading the code of the classes
to learn new classes of collections.