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

Ben Cohen ben_cohen at apple.com
Wed Sep 27 19:32:28 CDT 2017



> On Sep 27, 2017, at 12:44 PM, Tony Allevato <tony.allevato at gmail.com> wrote:
> 
> 
> 
> On Wed, Sep 27, 2017 at 10:36 AM Ben Cohen via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
> 
>> On Sep 25, 2017, at 2:12 AM, Alwyn Concessao via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> 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.
>> 
>> }
> 
> Hi Alwyn,
> 
> In general, we try to avoid methods on Collection in the standard library that take a limiting range to operate on.
> 
> This is something of a related aside, but since you mentioned it, is this also the reason that there is no method like `index(of element: Element, from index: Index) -> Index?`?
> 

Yep.

> In those situations where I've needed to do that (e.g., a while loop that skips from match to match) I end up falling back to slices, but historically it's been somewhat awkward to write compared to the code I would write if such a function exists.
> 
> That being said, I don't believe I've tried it since Swift 4 introduced the new partial range operators so it's possible that those simplify the pattern quite a bit.
> 

Hopefully! I’ve found it that way in practice e.g. https://gist.github.com/airspeedswift/e7e02943c4c4463da919a9a825f33def#file-lazysplit-swift-L14

An alternative pattern is to create a mutable slice variable, and continuously “eat” from the front of it, removing elements as you go (via removeFirst or similar). Eating from the front of a slice ought to just move the startIndex further along the base collection.

>  
> Instead, the user can slice the collection using the range, then call the mutating method on the slice. If done directly on the subscript, this has the effect of mutating the parent collection:
> 
> var a = Array(0..<10)
> let isEven = { $0%2 == 0 }
> 
> a[3...].remove(where: isEven)
> // a = [0, 1, 2, 3, 5, 7, 9]
> 
> The downside of this today is that it can be inefficient, because the mutated slice might be copied as part of the mutaate-and-write-back. But there are changes slated for Swift 5 that should allow this mutation to happen in place.
> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170927/59a3d403/attachment.html>


More information about the swift-evolution mailing list