Why no collect:ifNone: ?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Why no collect:ifNone: ?

Tim Mackinnon

Hi - I hit a small bug in my lunch experiments with Willow where I wanted to sum up a collection of support hours.

I was collect: in the hours worked and hadn’t accounted for an empty collection.

When I went to do it I was surprised there isn’t a concept of #collect:ifNone: that mirrors something like at:ifAbsent: or the nicely readable collect:thenXxx: methods.

Why is this?

I’m curious about style - and the elegance of my workaround :

result ifEmpty: [ 0 ] ifNotEmpty:[ :r | r collect: [:I | i hours ]]

which is ok, but seems a mouthful?

Am I missing a trick?

Tim

Sent from my iPhone

Reply | Threaded
Open this post in threaded view
|

Re: Why no collect:ifNone: ?

Esteban A. Maringolo
Hi Tim,

What I found confusing there is that with #select:thenCollect: or
#collect:thenXxx: you're always dealing with collections.

In your #collect:ifNone: there is a mix. You can return a collection
(#collect:) or the result of evaluating the emptyBlock, which in your
example is a number, so I it seems like a semantic mismatch smell to me.

Following your example:

myVar := result ifEmpty: [ 0 ] ifNotEmpty:[ :r | r collect: [:I | i
hours ]].

What will be in myVar? a collection? a number? something else?.

Maybe your example is too abstract to give a good feedback.

Regards,



On 30/04/2018 15:37, Tim Mackinnon wrote:

>
> Hi - I hit a small bug in my lunch experiments with Willow where I wanted to sum up a collection of support hours.
>
> I was collect: in the hours worked and hadn’t accounted for an empty collection.
>
> When I went to do it I was surprised there isn’t a concept of #collect:ifNone: that mirrors something like at:ifAbsent: or the nicely readable collect:thenXxx: methods.
>
> Why is this?
>
> I’m curious about style - and the elegance of my workaround :
>
> result ifEmpty: [ 0 ] ifNotEmpty:[ :r | r collect: [:I | i hours ]]
>
> which is ok, but seems a mouthful?
>
> Am I missing a trick?
>
> Tim
>
> Sent from my iPhone
>

--
Esteban A. Maringolo

Reply | Threaded
Open this post in threaded view
|

Re: Why no collect:ifNone: ?

Tim Mackinnon
In reply to this post by Tim Mackinnon
Yep - as I was reading the replies from you and Esteban - I was thinking there was something odd, and its correct, I’ve been careless - the problematic code had a trailing #sum to it, which is actually where the problem was….

total := schedule ifEmpty: [ 0 ] ifNotEmpty: [ :c |
                (c collect: [ :r | ((DateAndTime fromString: r end) - (DateAndTime fromString: r start)) asHours ]) sum ].

So you are both correct - it should have used inject.

total := schedule inject: 0 into: [ :result :item | result + ((DateAndTime fromString: item end) - (DateAndTime fromString: item start)) asHours ].

Oops - thanks for being my sound board.

Tim

> On 30 Apr 2018, at 22:02, Francisco Garau <[hidden email]> wrote:
>
>
> Have you tried #inject:into: ? Looks like what are needing here
>
> - Francisco
>
>
>> On 30 Apr 2018, at 19:37, Tim Mackinnon <[hidden email]> wrote:
>>
>>
>> Hi - I hit a small bug in my lunch experiments with Willow where I wanted to sum up a collection of support hours.
>>
>> I was collect: in the hours worked and hadn’t accounted for an empty collection.
>>
>> When I went to do it I was surprised there isn’t a concept of #collect:ifNone: that mirrors something like at:ifAbsent: or the nicely readable collect:thenXxx: methods.
>>
>> Why is this?
>>
>> I’m curious about style - and the elegance of my workaround :
>>
>> result ifEmpty: [ 0 ] ifNotEmpty:[ :r | r collect: [:I | i hours ]]
>>
>> which is ok, but seems a mouthful?
>>
>> Am I missing a trick?
>>
>> Tim
>>
>> Sent from my iPhone
>>


Reply | Threaded
Open this post in threaded view
|

Re: Why no collect:ifNone: ?

Tim Mackinnon
You can learn so much from these innocent questions.... Maximiliano pointed out that there is a difference between #sum and a method I never noticed #sumNumbers, the latter would avoided my problem too...

Sent from my iPhone

> On 30 Apr 2018, at 23:00, Tim Mackinnon <[hidden email]> wrote:
>
> Yep - as I was reading the replies from you and Esteban - I was thinking there was something odd, and its correct, I’ve been careless - the problematic code had a trailing #sum to it, which is actually where the problem was….
>
> total := schedule ifEmpty: [ 0 ] ifNotEmpty: [ :c |
>        (c collect: [ :r | ((DateAndTime fromString: r end) - (DateAndTime fromString: r start)) asHours ]) sum ].
>
> So you are both correct - it should have used inject.
>
> total := schedule inject: 0 into: [ :result :item | result + ((DateAndTime fromString: item end) - (DateAndTime fromString: item start)) asHours ].
>
> Oops - thanks for being my sound board.
>
> Tim
>
>> On 30 Apr 2018, at 22:02, Francisco Garau <[hidden email]> wrote:
>>
>>
>> Have you tried #inject:into: ? Looks like what are needing here
>>
>> - Francisco
>>
>>
>>> On 30 Apr 2018, at 19:37, Tim Mackinnon <[hidden email]> wrote:
>>>
>>>
>>> Hi - I hit a small bug in my lunch experiments with Willow where I wanted to sum up a collection of support hours.
>>>
>>> I was collect: in the hours worked and hadn’t accounted for an empty collection.
>>>
>>> When I went to do it I was surprised there isn’t a concept of #collect:ifNone: that mirrors something like at:ifAbsent: or the nicely readable collect:thenXxx: methods.
>>>
>>> Why is this?
>>>
>>> I’m curious about style - and the elegance of my workaround :
>>>
>>> result ifEmpty: [ 0 ] ifNotEmpty:[ :r | r collect: [:I | i hours ]]
>>>
>>> which is ok, but seems a mouthful?
>>>
>>> Am I missing a trick?
>>>
>>> Tim
>>>
>>> Sent from my iPhone
>>>
>
>