Additional methods for removing elements from a collection in Swift

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

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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Hi Alwyn,

In general, we try to avoid methods on Collection in the standard library that take a limiting range to operate on. 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.

···

On Sep 25, 2017, at 2:12 AM, Alwyn Concessao via swift-evolution <swift-evolution@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.

}

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.

···

On Mon, Sep 25, 2017 at 11:14 Félix Cloutier via swift-evolution < swift-evolution@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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?`?

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.

···

On Wed, Sep 27, 2017 at 10:36 AM Ben Cohen via swift-evolution < swift-evolution@swift.org> wrote:

On Sep 25, 2017, at 2:12 AM, Alwyn Concessao via swift-evolution < > swift-evolution@swift.org> wrote:

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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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 4:55 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Sep 25, 2017 at 11:14 Félix Cloutier via swift-evolution < > swift-evolution@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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@gmail.com> a écrit :

On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

What is the use case?

···

On Mon, Sep 25, 2017 at 23:27 Félix Cloutier <felixcloutier@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@gmail.com> a écrit :

On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Yeah, IMO it’s fair to add this function.

I also think we should have a way of removing elements at multiple indexes (e.g. from a generic sequence of indexes). That’s something that naïve programmers are more likely to get wrong.

- Karl

···

On 26. Sep 2017, at 06:27, Félix Cloutier via swift-evolution <swift-evolution@swift.org> 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@gmail.com <mailto:xiaodi.wu@gmail.com>> a écrit :

On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

···

On Sep 27, 2017, at 12:44 PM, Tony Allevato <tony.allevato@gmail.com> wrote:
On Wed, Sep 27, 2017 at 10:36 AM Ben Cohen via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Sep 25, 2017, at 2:12 AM, Alwyn Concessao via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

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@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

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@swift.org> wrote:

What is the use case?
On Mon, Sep 25, 2017 at 23:27 Félix Cloutier <felixcloutier@icloud.com <mailto:felixcloutier@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@gmail.com <mailto:xiaodi.wu@gmail.com>> a écrit :

On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Same as `filter`, but in-place. We thought that `sorted` deserved an in-place version; that +(Array, Array) deserved an in-place version (append(contentsOf:)); there are parallels to be made between `dropFirst` and `removeFirst`; we have index and formIndex. There's a ton more, Swift loves to have a mutating and a non-mutating version of everything. Not sure why we should break consistency and not have an in-place version of filter.

Félix

···

Le 25 sept. 2017 à 21:55, Xiaodi Wu <xiaodi.wu@gmail.com> a écrit :

What is the use case?
On Mon, Sep 25, 2017 at 23:27 Félix Cloutier <felixcloutier@icloud.com <mailto:felixcloutier@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@gmail.com <mailto:xiaodi.wu@gmail.com>> a écrit :

On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

Probably would have been better to go with a mutating filter and a non-mutating filtered, terms-of-art be damned. Remove seems like an subpar substitute for that.

···

On Sep 26, 2017, at 12:55 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

What is the use case?

On Mon, Sep 25, 2017 at 23:27 Félix Cloutier <felixcloutier@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@gmail.com> a écrit :

On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

First of all thanks to you all for the suggestions/thoughts on this idea.
@Jonathan Hull - You've mentioned about splitting a list using a filter which returns the filtered list and the remainder.Is it similar to having a filter function which does the filtering on the original collection and also returns the elements which are removed from the collection?

@Félix Cloutier and @Robert Bennett - Yes, in-place filter method is not provided by Swift.The in-place filter method would also take care of removing elements without actually accessing it's index.
Alwyn On Tuesday, 26 September 2017, 12:00:23 PM IST, Félix Cloutier <felixcloutier@icloud.com> wrote:

Same as `filter`, but in-place. We thought that `sorted` deserved an in-place version; that +(Array, Array) deserved an in-place version (append(contentsOf:)); there are parallels to be made between `dropFirst` and `removeFirst`; we have index and formIndex. There's a ton more, Swift loves to have a mutating and a non-mutating version of everything. Not sure why we should break consistency and not have an in-place version of filter.
Félix

···

Le 25 sept. 2017 à 21:55, Xiaodi Wu <xiaodi.wu@gmail.com> a écrit :
What is the use case?
On Mon, Sep 25, 2017 at 23:27 Félix Cloutier <felixcloutier@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@gmail.com> a écrit :
On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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

···

On Tue, Sep 26, 2017 at 00:15 Jonathan Hull <jhull@gbis.com> wrote:

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@swift.org> wrote:

What is the use case?
On Mon, Sep 25, 2017 at 23:27 Félix Cloutier <felixcloutier@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@gmail.com> a écrit :

On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________

swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

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).

There’s partition(by:), which gives you an index that you can split with.

···

Sent from my iPhone

On Sep 25, 2017, at 22:16, Jonathan Hull via swift-evolution <swift-evolution@swift.org> wrote:

Thanks,
Jon

On Sep 25, 2017, at 9:55 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

What is the use case?
On Mon, Sep 25, 2017 at 23:27 Félix Cloutier <felixcloutier@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@gmail.com> a écrit :

On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Considering some of the suggestions which have come up here I'm glad to say that I have been able to achieve the in-place filter and remove(where:) functionalities by using existing APIs.

Alwyn

···

On Tuesday, 26 September 2017, 4:47:48 PM IST, Karl Wagner <razielim@gmail.com> wrote:

Yeah, IMO it’s fair to add this function.
I also think we should have a way of removing elements at multiple indexes (e.g. from a generic sequence of indexes). That’s something that naïve programmers are more likely to get wrong.
- Karl

On 26. Sep 2017, at 06:27, Félix Cloutier via swift-evolution <swift-evolution@swift.org> 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@gmail.com> a écrit :
On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@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@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@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@swift.org
https://lists.swift.org/ mailman/listinfo/swift- evolution

______________________________ _________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/ mailman/listinfo/swift- evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Hmm… I suppose a remove(where:) that had a @discardableResult of the things being removed would be useful in this way. Not to mention that it would be consistent with what I expect from a function called remove.

I was already in support, but now even more so…

Thanks,
Jon

···

On Sep 26, 2017, at 2:37 AM, Alwyn Concessao <alsav196@yahoo.com> wrote:

@Jonathan Hull - You've mentioned about splitting a list using a filter which returns the filtered list and the remainder.Is it similar to having a filter function which does the filtering on the original collection and also returns the elements which are removed from the collection?

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@gmail.com> wrote:

On Tue, Sep 26, 2017 at 00:15 Jonathan Hull <jhull@gbis.com <mailto:jhull@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@swift.org <mailto:swift-evolution@swift.org>> wrote:

What is the use case?
On Mon, Sep 25, 2017 at 23:27 Félix Cloutier <felixcloutier@icloud.com <mailto:felixcloutier@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@gmail.com <mailto:xiaodi.wu@gmail.com>> a écrit :

On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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@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@gmail.com> wrote:

On Tue, Sep 26, 2017 at 00:15 Jonathan Hull <jhull@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@swift.org> wrote:

What is the use case?
On Mon, Sep 25, 2017 at 23:27 Félix Cloutier <felixcloutier@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@gmail.com> a écrit :

On Mon, Sep 25, 2017 at 4:55 PM, Xiaodi Wu <xiaodi.wu@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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________

swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution