ArrayList<String> strings = new ArrayList<String>();
for(Person person: persons)
strings.add(person.name());
is expressed as
strings := persons collect: [ :person | person name ]
strings = persons.stream().map(person -> person.getName())
collect:
applies the block to each element and returns a collection (of the same kind than the receiver) with the results
#(2 -3 4 -35 4) collect: [ :each | each abs ]
> #(2 3 4 35 4)
collect:
evaluates the block for each element (using value:
)abs
(absolute) collect:
returns a new collection (of the same kind of the receiver) with all resultsWe want to know if each elements is odd or even
#(16 11 68 19) collect: [ :i | i odd ]
> #(false true false true)
#(16 11 68 19) collect: [ :i | i odd ]
We can also do it that way! (We copied the definition of collect:
)
| result |
aCol := #(16 11 68 19).
result := aCol species new: aCol size.
1 to: aCollection size do:
[ :each | result at: each put: (aCol at: each) odd ].
^ result
Iterators work polymorphically on the entire collection hierarchy. Below a part of the Collection hierarchy.
do:
(iterate)collect:
(iterate and collect results)select:
(select matching elements)reject:
(reject matching elements)detect:
(get first element matching)detect:ifNone:
(get first element matching or a default value)includes:
(test inclusion)#(16 11 68 19) do: [ :each | Transcript show: each ; cr ]
Here we print each element and insert a carriage return
To select some elements, use select:
#(16 11 68 19) select: [ :i | i odd ]
> #(11 19)
When a block is just one message, we can pass an unary message selector
#(16 11 68 19) select: [ :i | i odd ]
is equivalent to
#(16 11 68 19) select: #odd
To filter some elements, use reject:
#(16 11 68 19) reject: [ :i | i odd ]
> #(16 68)
To find the first element that matches, use detect:
#(16 11 68 19) detect: [ :i | i odd ]
> 11
To find the first element that matches else return a value, use detect:ifNone:
#(16 12 68 20) detect: [ :i | i odd ] ifNone: [ 0 ]
> 0
anySatisfy:
(tests if one object is satisfying the criteria)allSatisfy:
(tests if all objects are satisfying the criteria)reverseDo:
(do an action on the collection starting from the end)doWithIndex:
(do an action with the element and its index)pairsDo:
(evaluate aBlock with my elements taken two at a time.)permutationsDo:
...
To iterate with:do:
#(1 2 3)
with: #(10 20 30)
do: [ :x :y | Transcript show: (y * x) ; cr ]
with:do:
requires two structures of the same length
String streamContents: [ :s |
#('a' 'b' 'c')
do: [ :each | s << each ]
separatedBy: [ s << ', ' ]
]
> 'a, b, c'
To group elements according to a grouping function: groupedBy:
#(1 2 3 4 5 6 7) groupedBy: #even
> a PluggableDictionary(false->#(1 3 5 7) true->#(2 4 6) )
How to remove one level of nesting in a collection? Use flatCollect:
#( #(1 2) #(3) #(4) #(5 6)) collect: [ :each | each ]
> #(#(1 2) #(3) #(4) #(5 6)))
#( #(1 2) #(3) #(4) #(5 6)) flatCollect: [ :each | each ]
> #(1 2 3 4 5 6 )
do:
is implemented?SequenceableCollection >> do: aBlock
"Evaluate aBlock with each of the receiver's elements as the argument."
1 to: self size do: [:i | aBlock value: (self at: i)]
/