[swift-evolution] Additional methods for removing elements from a collection in Swift

Xiaodi Wu xiaodi.wu at gmail.com
Tue Sep 26 05:48:10 CDT 2017


That is very nice. Unless someone can show how this can be easily achieved
in an ergonomic way with today’s APIs, I am on board with remove(where:).
On Tue, Sep 26, 2017 at 05:28 Jonathan Hull <jhull at gbis.com> wrote:

> Alwyn just pointed out another use-case as well.
>
> If there is either a @discardableResult or two variants (one which returns
> a result) where the method returns the items being removed (which is to be
> expected of a method named “remove”), then it becomes useful in ways which
> filter alone is not.  Here is how it would be used with a use-case from a
> project I was working on this weekend:
>
> var longWords = allWords //A very long list of words passed as a parameter
> let shortWords = longWords.remove(where: {$0.characters.count < 4})
>
> compare that to either filtering twice:
> let longWords = allWords.filter({$0.characters.count >= 4})
> let shortWords = allWords.filter({$0.characters.count < 4}) //We are
> looping over a very long list twice
>
> or what I ended up doing:
>
> var longWords:[String] = []
> var shortWords:[String] = []
> for word in allWords {
> if word.characters.count < 4 {
> shortWords.append(word)
> }else{
> longWords.append(word)
> }
> }
>
>
> Thanks,
> Jon
>
> On Sep 26, 2017, at 2:59 AM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
>
> On Tue, Sep 26, 2017 at 00:15 Jonathan Hull <jhull at gbis.com> wrote:
>
>> As he says, it is an in-place equivalent of filter, so the use-cases
>> would be similar.  I could see this being extremely useful.  Off the top of
>> my head:
>>
>> views.remove(where: {$0.isHidden}) //Remove all views which are hidden
>> from the list.
>>
>
> Is such a method ever going to be different (in performance, say) from:
>
> views = Views(views.lazy.filter { $0.isHidden })
>
> Another thing which seems to be missing (although it could be there and I
>> don’t know the name) is the ability to split a list into two using a filter
>> (one with the filtered items and one with the remainder).  I am surprised
>> every time I reach for it and it isn’t there (the last time being
>> yesterday).
>>
>> Thanks,
>> Jon
>>
>>
>>
>> On Sep 25, 2017, at 9:55 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> What is the use case?
>> On Mon, Sep 25, 2017 at 23:27 Félix Cloutier <felixcloutier at icloud.com>
>> wrote:
>>
>>> Actually, IMO, it's an oversight that there's no remove(where:), or
>>> another in-place equivalent to `filter`. I'm in favor of it.
>>>
>>> Félix
>>>
>>>
>>> Le 25 sept. 2017 à 15:17, Xiaodi Wu <xiaodi.wu at gmail.com> a écrit :
>>>
>>> On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>>
>>>> Brent has a great proposal in the pipeline regularizing the names of
>>>> some of these functions and filling in some of the more glaring gaps.
>>>>
>>>> With regard to the specific items proposed here, Felix shows that
>>>> ‘filter’ provides an idiomatic one-line way of doing some of what is
>>>> proposed; currently remove(index(of:)) and operating on sliced would
>>>> accomplish the rest. Therefore, I do not think these proposed additions
>>>> meet the very high bar for expansion of the standard library API.
>>>
>>>
>>> I should add, however, it is wonderful (IMO) that more people are
>>> thinking about these APIs; welcome and thank you for restarting this very
>>> important conversation. It would be nice to get some more eyeballs on the
>>> previously discussed set of rationalizations to the Collection APIs so that
>>> we can make their use a little more ergonomic--with any luck, some better
>>> names for existing extension methods and filling in a very few gaps
>>> judiciously would allow us to make the existing facilities sufficiently
>>> more discoverable that it will be easier to accomplish what you seek
>>> without adding more extensions.
>>>
>>>
>>> On Mon, Sep 25, 2017 at 11:14 Félix Cloutier via swift-evolution <
>>>> swift-evolution at swift.org> wrote:
>>>>
>>>>> Another alternative is to use `array = array.filter { $0 !=
>>>>> someElement }`.
>>>>>
>>>>> I thought that there would be a `remove(where:)` method, but there
>>>>> isn't.
>>>>>
>>>>> Félix
>>>>>
>>>>> Le 25 sept. 2017 à 02:12, Alwyn Concessao via swift-evolution <
>>>>> swift-evolution at swift.org> a écrit :
>>>>>
>>>>> Hello,
>>>>>
>>>>> After going through the Swift standard library functions provided for
>>>>> removing elements from a collection, one common pattern can be observed in
>>>>> all those functions and that is the functions provide to remove elements
>>>>> from the collection by passing the position or index of the element or
>>>>> passing a range of indices or positions to remove the elements.The standard
>>>>> library does not provide options to remove an element from a collection by
>>>>> passing the actual element  to be removed directly to the remove
>>>>> method.I've encountered this situation many times when programming in Swift
>>>>> wherein I want an element or a set of elements to be removed directly
>>>>> without always accessing it's index in the collection but I have always
>>>>> ended up having to first access the index of the element or elements which
>>>>> I want to remove and then pass that index to the remove method.
>>>>>
>>>>> The idea is to have an extension of the RangeReplaceableCollection
>>>>> protocol to include a method to remove elements from a collection by
>>>>> passing directly the element to be removed to the remove method and also
>>>>> include methods to remove multiple elements from the collection by passing
>>>>> in a sequence of the elements to be removed to the remove method and to
>>>>> remove an element in a particular subrange of the collection.
>>>>>
>>>>> The prototype of the methods will be as follows -
>>>>>
>>>>> extension RangeReplaceableCollection where Element:Equatable{
>>>>>
>>>>> mutating func removeElement(_ elementToBeRemoved:Element){
>>>>>
>>>>> //check if elementToBeRemoved exists ;if yes, remove all occurrences
>>>>> of elementsToBeRemoved from the collection.
>>>>>
>>>>> }
>>>>>
>>>>> mutating func removeElementInSubrange(_ elementToBeRemoved:Element,in
>>>>> range:Range<Index>){
>>>>>
>>>>> //check if elementoBeRemoved exists; if yes, check if the index of
>>>>> elementToBeRemoved is part of the subrange, if yes then remove else don't
>>>>> remove.
>>>>>
>>>>> }
>>>>>
>>>>> mutating func removeContentsOf<C:Collection>(_ elementsToBeRemoved:C){
>>>>>
>>>>> //check if each element in the elementsToBeRemoved sequence exists in
>>>>> the collection, if the element exists, remove it.
>>>>>
>>>>> }
>>>>>
>>>>> I've implemented the above in the pull request
>>>>> https://github.com/apple/swift/pull/12058
>>>>>
>>>>> Any thoughts/suggestions on this are appreciated.
>>>>>
>>>>> Thanks!
>>>>>
>>>>> Alwyn
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>
>>>>
>>>
>>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170926/78256d65/attachment.html>


More information about the swift-evolution mailing list