Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking issue for Vec::remove_item #40062

Open
madseagames opened this Issue Feb 23, 2017 · 32 comments

Comments

Projects
None yet
@madseagames
Copy link
Contributor

madseagames commented Feb 23, 2017

Implemented in #40325

impl<T: PartialEq> Vec<T> {
    pub fn remove_item(&mut self, item: &T) -> Option<T> { /*…*/ }
}
@clarfon

This comment has been minimized.

Copy link
Contributor

clarfon commented Mar 8, 2017

PR moved to #40325 due to reasons

@clarfon

This comment has been minimized.

Copy link
Contributor

clarfon commented Mar 8, 2017

Comments from original thread:

  1. I think that we should add this method to VecDeque too.
  2. Is remove_last_item desired?
@madseagames

This comment has been minimized.

Copy link
Contributor Author

madseagames commented Mar 8, 2017

@clarcharr for remove_last_item you can simply do vec.remove(vec.len() - 1))

@clarfon

This comment has been minimized.

Copy link
Contributor

clarfon commented Mar 8, 2017

@madseagames I meant specifically a method that searches for the item from the end of the vec instead of the beginning

@oberien

This comment has been minimized.

Copy link
Contributor

oberien commented Mar 15, 2017

What do you think about adding remove_swap_item? Just as remove_swap reduces the runtime complexity from O(n) to O(1) compared to remove, remove_swap_item would reduce it from O(n + (n-m)) to O(n).

@clarfon

This comment has been minimized.

Copy link
Contributor

clarfon commented Mar 15, 2017

I like swap_remove_item.

@MarkSwanson

This comment has been minimized.

Copy link

MarkSwanson commented Jun 3, 2017

It would be nice if this was more generic.
let v: Vec = Vec::new();
v.remove_item("s"); <-- fails because &str is not a &String

we really want the remove_item "item: &T" to be "something that we can compare equality with the type in the container". This would let remove_item() walk the T items, compare equality, and remove if equal.

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Jun 3, 2017

Seems reasonable to change the signature to fn remove_item<U>(&mut self, item: &U) -> Option<T> where T: PartialEq<U> + ?Sized

@leodasvacas

This comment has been minimized.

Copy link
Contributor

leodasvacas commented Aug 18, 2017

Reviewing the naming used in method names and the docs, it would seem that iterators yield items while vecs contain elements. Considering that we insert elements then we should also remove elements and the method should be called remove_element. That name is a bit long so I'd propose simply remove_eq. However I wonder if we should favor a more general remove_by, or have both.

fn remove_by<F: FnMut(&T) -> bool>(&mut self, f: F)
@zbraniecki

This comment has been minimized.

Copy link

zbraniecki commented Jan 29, 2018

Any plan to stabilize this?

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Mar 17, 2018

This has been in nightly for a year with no issue reported on the method itself. There are proposals for additional methods, but that shouldn’t block this one. Please submit separate PRs or RFCs.

@rfcbot fcp merge

@rfcbot

This comment has been minimized.

Copy link

rfcbot commented Mar 17, 2018

Team member @SimonSapin has proposed to merge this. The next step is review by the rest of the tagged team members:

Concerns:

Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Mar 17, 2018

Are we switching to a V: PartialEq<T> bound?

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Mar 17, 2018

Oops, sorry I missed that. Yes, let’s.

@gnzlbg

This comment has been minimized.

Copy link
Contributor

gnzlbg commented Mar 18, 2018

Again here, as a maintainer of collections that offer the Vec and VecDeque APIs I'd like at least a summary comment explaining what this method does, why this design was followed, alternatives, and addressing the issues mentioned here that have received zero replies:

  • should this method be added to VecDeque?
  • @sfackler :

Seems reasonable to change the signature to fn remove_item<U>(&mut self, item: &U) -> Option<T> where T: PartialEq<U> + ?Sized

  • @leodasvacas naming issue: why items instead of elements? why remove_items instead of remove_by, etc.
@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Mar 19, 2018

@rfcbot concern rationale-and-vecdeque

Just gonna formally register @gnzlbg's concern above

@kornelski

This comment has been minimized.

Copy link
Contributor

kornelski commented Apr 11, 2018

Not an issue with the method per se, but it may need to be very clearly documented that the reference is not supposed to be to an item that is in the Vec already, as it creates impossible borrow-checker conundrum.

Users coming from the C world of pointers but no proper equality comparison, may be confused by this method, e.g. https://users.rust-lang.org/t/difficult-borrowing-situation/16794

The remove_eq name mentioned previously would help.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented May 17, 2018

@SimonSapin as the proposer for FCP, do you have thoughts on @gnzlbg's concern?

@droundy

This comment has been minimized.

Copy link
Contributor

droundy commented Sep 3, 2018

My thinking is that the remove_by suggested by @leodasvacas would sidestep most of the issues here.

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Dec 29, 2018

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Dec 29, 2018

I don’t have a strong desire for this particular feature myself, I proposed FCP as an effort to reduce the number of features in "unstable limbo". That said:

Regarding VecDeque, sure, I don’t see a reason not to add it there as well.

remove_by as proposed in #40062 (comment) sounds good to me. It is more general, and goes with precedent of Iterator::position also taking a boolean callable predicate rather than relying on PartialEq. (Even further, the precedent of Iterator not having a method like position that would rely on PartialEq.)

@withoutboats

This comment has been minimized.

Copy link
Contributor

withoutboats commented Dec 29, 2018

I notice two things:

  1. There are a lot of methods similar to this we could add, and its not obvious to me which set of those methods is the ideal set.
  2. This has sat in FCP concern limbo for 8 months without anyone complaining.

I think we should not stabilize this just because it exists, but instead someone should come up with a well justified explanation of exactly what the best "find and remove" set of methods of vec-likes would be.

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Dec 29, 2018

Good points.

drain (which is stable) and drain_filter #43244 also fit the "find and remove" description, and we had a similar concern #43244 (comment) about the combinations of filtering v.s. non-filtering and self-exhausting on drop (rust-lang/rfcs#2369) v.s. not.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Feb 20, 2019

@rfcbot resolve rationale-and-vecdeque

I don't want to personally be on the hook for blocking this any more

@rfcbot

This comment has been minimized.

Copy link

rfcbot commented Feb 20, 2019

🔔 This is now entering its final comment period, as per the review above. 🔔

@rfcbot

This comment has been minimized.

Copy link

rfcbot commented Mar 2, 2019

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

The RFC will be merged soon.

@leodasvacas

This comment has been minimized.

Copy link
Contributor

leodasvacas commented Mar 7, 2019

I still think this should be called remove_eq instead of remove_item.

@mathstuf

This comment has been minimized.

Copy link
Contributor

mathstuf commented Mar 7, 2019

My problem with that name is that it only removes the first matching item, not all that are eq (though I haven't read the relevant RFC to know whether the name has been hashed out already; I assume it has been).

@kornelski

This comment has been minimized.

Copy link
Contributor

kornelski commented Mar 9, 2019

I don't think the naming issue has been resolved. The implementation is still using the confusing remove_item name.

@mathstuf remove_first_eq then?

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Mar 26, 2019

@rust-lang/libs Can someone clarify what the status of this is wrt. the conversation above?

@Boiethios

This comment has been minimized.

Copy link

Boiethios commented Apr 4, 2019

I notice two things:

1. There are a lot of methods similar to this we could add, and its not obvious to me which set of those methods is the ideal set.

2. This has sat in FCP concern limbo for 8 months without anyone complaining.

I think we should not stabilize this just because it exists, but instead someone should come up with a well justified explanation of exactly what the best "find and remove" set of methods of vec-likes would be.

An example: I'm writing a proc macro attribute, and amongst the tokens, I expect other attribute to be there. This would be useful to add:

if let Some(attr) = attrs.remove_item(|item| attr.path.is_ident("foo")) {
    // Handle the `foo` attribute case...
}
@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Apr 4, 2019

@Boiethios Until we sort this out, you can use attrs.iter().position(|item| some_boolean(item)).map(|i| attrs.remove(i))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.