-
Notifications
You must be signed in to change notification settings - Fork 431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Property.filter #586
Add Property.filter #586
Conversation
14feb5f
to
1ae9ca6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Back in the times when introducing property composition, I had considered having these lifted to output optionals, but apparently that would be nasty to consume.
I'd approve but we probably need more eyes on this, since it'd set a precedence for future property operators. cc @ReactiveCocoa/reactiveswift
CHANGELOG.md
Outdated
@@ -1,6 +1,8 @@ | |||
# master | |||
*Please add new entries at the top.* | |||
|
|||
1. `Property`s now have a `filter` operator. (#586, kudos to @iv-mexx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Nit] New property operator: filter
. 😛
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Sources/Property.swift
Outdated
/// | ||
/// - returns: A property that holds only values from `self` passing the given predicate. | ||
public func filter(initial: Value, _ predicate: @escaping (Value) -> Bool) -> Property<Value> { | ||
return Property.init(initial: initial, then: self.producer.filter(predicate)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove .init
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
As a side note though, we often deal with streams of things we do not own (a la non instantiatable). In those cases optionality is a must, and we could do it in two ways:
Going after (1) hampers simple use cases, when there is an obvious initial value, e.g. some sort of flag derived from the content. Meanwhile, despite (2) hampering cases with mandatory optionality in favour of simple uses, it is also IMO more explicit. |
1ae9ca6
to
fa436b8
Compare
I had considered that as well at first, but it was indeed awkward to use. |
I'm curious why you found it awkward to use. Returning a It does seem like either way would get painful if you were going to chain multiple things together: property
.filter(initial: 1, condition1)
.filter(initial: 1, condition2) It'd be nice if we had could do something to propagate that through with some sentinel value. But I don't think that possible with the current APIs. 🤔 |
"Awkward" may be the wrong word for it. Basically, it feels strange to me to introduce an optional, when "just" the initial value is missing, something that I have to deal with regardless of the I often have (Mutable) properties that will always have a value, but a first "valid" value is not available at initialization. Since the value will not change back to nil, using an optional fells wrong and is often tedious down the line, so I have to find a suitable initial value anyway, e.g. empty string, empty array, ...
This would be really great in my described use case but goes way over my head implementation wise 😆
Yeah,i f you think |
I think I'm on board with passing in the initial value like you have here. I don't see a truly better option. |
Another (possibly stupid) idea would be to have the new property always start with the current value of the existing property and then filter all subsequent values. I think this would make the operator pretty seamless to use in most cases, though it might make it too easy to make a mistake. |
Thanks @iv-mexx! |
Checklist
A
filter
operator forProperty
has one edge case:Property
always needs to have a value, but what if the predicate excludes the current (or all) values of the sourceProperty
?Probably thats the reason that this operator was not yet included for Property?
I suggest to provide an initial value for the filtered
Property
to handle that case.