想象一下,您必须选择一些值,并且对于每个值,您必须评估一个块。另一方面,如果没有满足条件的值,则必须评估另一个块。
示例: 考虑下一个方法签名:
forPositivesOf: aCollection do: aBlock otherwise: defaultBlock
此方法应使用aBlock
的每个正元素评估一个块aCollection
,但如果没有这样的元素,请评估defaultBlock
。请注意,实际上该方法可能会计算出比正数更复杂的东西,而不是aCollection,可能会有更复杂的对象。
答案 0 :(得分:4)
第一个替代方案的更紧凑版本是以下内容,它不会实例化新的闭包,只使用作为参数接收的闭包。
forPositivesOf: aCollection do: aBlock otherwise: defaultBlock
^(aCollection select: [:each | each positive ])
ifEmpty: defaultBlock
ifNotEmpty: [ :collection | collection do: aBlock ]
答案 1 :(得分:1)
目前我看到两个解决方案:
<强> 1)强>
forPositivesOf: aCollection do: aBlock otherwise: defaultBlock
(aCollection select: #positive)
ifEmpty: [ defaultBlock value ]
ifNotEmpty: [ :collection |
collection do: [ :el | aBlock cull: el ] ]
但是如果positive
的计算成本很高,那么评估aBlock
第一个遇到的元素会很好,因为那个通过aBlock
的人将能够做出任何反应。想要的方式。
<强> 2)强>
forPositivesOf: aCollection do: aBlock otherwise: defaultBlock
| encountered |
encountered := false.
aCollection do: [ :el |
el positive ifTrue: [
encountered := true.
aBlock cull: el ] ].
encountered ifFalse: [
defaultBlock value ]
但我不喜欢额外遇到的变量,它会降低代码的功能。
答案 2 :(得分:1)
进一步采用Uko的解决方案:
forPositivesOf: aCollection do: aBlock otherwise: defaultBlock
^ (aCollection
select: #positive
thenCollect: aBlock
) ifEmpty: defaultBlock
答案 3 :(得分:0)
一种非常好的功能方式适用于 SequenceableCollection :
forPositivesOf: aCollection do: aBlock otherwise: defaultBlock
(aCollection
select: #positive
thenCollect: [ :el | aBlock cull: el ]) ifEmpty: [ defaultBlock value ]