Skip to content
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

filterElement to filter inner sequence ? #261

Open
npvisual opened this issue May 5, 2020 · 3 comments
Open

filterElement to filter inner sequence ? #261

npvisual opened this issue May 5, 2020 · 3 comments

Comments

@npvisual
Copy link
Contributor

npvisual commented May 5, 2020

I was wondering if we could add a new function in the SignalProtocol+Sequence.swift file that would allow to filter the elements of a sequence of a signal.

For example :

extension SignalProtocol where Element: Sequence {
    
    /// Filter inner sequence.
    public func filterElement(_ isIncluded: @escaping (Element.Iterator.Element) -> Bool) -> Signal<Element, Error> {
        return self.map { $0.filter(isIncluded) as! Self.Element }
    }
}

... or something along those lines.

Since we already have mapElement, it seems that filterElement is only appropriate (?).

@srdanrasic
Copy link
Contributor

Sure, I think that would be a nice addition. I suggest a slightly different implementation to avoid the force unwrap though:

extension SignalProtocol where Element: Sequence {
    
    /// Filter inner sequence.
    public func filterElement(_ isIncluded: @escaping (Element.Iterator.Element) -> Bool) -> Signal<[Element.Iterator.Element], Error> {
        return self.map { $0.filter(isIncluded) }
    }
}

@npvisual
Copy link
Contributor Author

npvisual commented May 6, 2020

Yes, I tried that before but I am getting a fairly complicated return type, rather than the initial Sequence-confirming type that was provided (which could be constrained even more to Collection, I guess).

For example, if I feed it a Dictionary<String, ParticipantDetails>, I get the following after I apply the filter :

'[Dictionary<String, ParticipantDetails>.Iterator.Element]' (aka 'Array<(key: String, value: ParticipantDetails)>')

I don't like the force unwrap either. However if we're trying to make this generic over the Sequence-conforming type shouldn't we return the same type (i.e. a [String: ParticipantDetails] in my case) ?

@srdanrasic
Copy link
Contributor

Ah, good point. Looks like RangeReplaceableCollection declares a filter function that returns Self, so we could do:

extension SignalProtocol where Element: RangeReplaceableCollection {

    public func filterElement(_ isIncluded: @escaping (Element.Element) -> Bool) -> Signal<Element, Error> {
        return self.map { $0.filter(isIncluded) }
    }
}

Which is nice, but Dictionary and Set are not RangeReplaceableCollections. We could implement additional overloads that cover those collections:

extension SignalProtocol {

    public func filterElement<K, V>(_ isIncluded: @escaping (Element.Element) -> Bool) -> Signal<[K: V], Error> where Element == [K: V] {
        return self.map { $0.filter(isIncluded) }
    }
}

extension SignalProtocol {

    public func filterElement<V>(_ isIncluded: @escaping (Element.Element) -> Bool) -> Signal<Set<V>, Error> where Element == Set<V> {
        return self.map { $0.filter(isIncluded) }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants