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

Add drain_filter for BinaryHeap #42849

Open
RalfJung opened this issue Jun 23, 2017 · 22 comments
Open

Add drain_filter for BinaryHeap #42849

RalfJung opened this issue Jun 23, 2017 · 22 comments
Assignees
Labels
A-collections Area: std::collections. C-feature-accepted Category: A feature request that has been accepted pending implementation. E-help-wanted Call for participation: Help is requested to fix this issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@RalfJung
Copy link
Member

RalfJung commented Jun 23, 2017

std::collections::BinaryHeap is missing a drain_filter method (rust-lang/rfcs#2140).

@Mark-Simulacrum Mark-Simulacrum added C-feature-request Category: A feature request, i.e: not implemented / a PR. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Jun 23, 2017
@dtolnay dtolnay added C-feature-accepted Category: A feature request that has been accepted pending implementation. and removed C-feature-request Category: A feature request, i.e: not implemented / a PR. labels Nov 15, 2017
@dtolnay
Copy link
Member

dtolnay commented Nov 15, 2017

Sounds good to me. I agree that this part of the API would be good to keep consistent between HashMap/HashSet and BTreeMap/BTreeSet. Please submit a PR.

@nbro

This comment was marked as spam.

@Mark-Simulacrum

This comment was marked as outdated.

@nbro

This comment was marked as outdated.

@Mark-Simulacrum Mark-Simulacrum changed the title Add retain() and drain() for BTreeMap/BTreeSet Add retain() and drain() for BTreeMap, BTreeSet, BinaryHeap Jun 4, 2018
@Ryan1729
Copy link
Contributor

If someone ever gets around to this, it would be a shame to repeat the mistake of passing &T like in the Vec retain implementation. These methods should pass &mut T to the closure, like the HashMap implementation does.

@jq-rs

This comment has been minimized.

@Mark-Simulacrum

This comment has been minimized.

@jq-rs
Copy link

jq-rs commented Sep 13, 2018

Getting nowhere so far, so I'll pass this to future volunteers.

@jonhoo
Copy link
Contributor

jonhoo commented Mar 18, 2019

BinaryHeap now has drain, although for some reason it removes elements in arbitrary order (#59278) :/

@hellow554
Copy link
Contributor

hellow554 commented Mar 18, 2019

[...] it removes elements in arbitrary order (#59278) :/

Is that really a problem? I can't think of a situation where you want to remove elements in order.

Ah sure, it's about iterating in a specific order, not removing (was confused with retain)

@jonhoo
Copy link
Contributor

jonhoo commented Mar 18, 2019

I mean, it's a heap... If I want to re-use the heap, it seems pretty reasonable to use .drain to walk the heap rather than a while let Some(_) = heap.pop loop. I think this is especially surprising for IntoIterator -- it'd be like a BTreeMap yielding elements in a random order when you do for (k, v) in btreemap.

@czipperz
Copy link
Contributor

Is it acceptable to implement this using brute force and then redo it later for performance gains? Just do something like:

let this = mem::replace(self, Default::default());
*self = this.into_iter().filter(...).collect();

@jonas-schievink jonas-schievink added E-help-wanted Call for participation: Help is requested to fix this issue. A-collections Area: std::collections. E-needs-mentor labels Jun 6, 2019
@gendx

This comment has been minimized.

@ssomers

This comment has been minimized.

@gendx

This comment has been minimized.

@ssomers
Copy link
Contributor

ssomers commented Dec 5, 2019

It turns out that a drain without range is trivial. An excerpt from simple code on playground comparing to an existing drain:

        for i in v[0].drain(..) {}
        for i in std::mem::replace(&mut m[0], BTreeSet::new()).into_iter() {}

So I think it's only worth the trouble if it operates on a range.

Secondly, I wondered why retain doesn't take a range either, but that's what drain_filter is for (the #59618 mentioned above). It might die like #1353 did, but more likely it means retain will be useless and we want drain_filter instead.

@ssomers

This comment has been minimized.

arlopurcell pushed a commit to arlopurcell/rust that referenced this issue Apr 24, 2020
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Apr 24, 2020
…manieu

Add BinaryHeap::retain as suggested in rust-lang#42849

This PR implements retain for BinaryHeap as suggested in rust-lang#42849.

This is my first PR for Rust, so please let me know if I should be doing anything differently, thanks!
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Apr 24, 2020
…manieu

Add BinaryHeap::retain as suggested in rust-lang#42849

This PR implements retain for BinaryHeap as suggested in rust-lang#42849.

This is my first PR for Rust, so please let me know if I should be doing anything differently, thanks!
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 24, 2020
Rollup of 8 pull requests

Successful merges:

 - rust-lang#69456 (fix misleading type annotation diagonstics)
 - rust-lang#71330 (Only run dataflow for const qualification if type-based check would fail)
 - rust-lang#71480 (Improve PanicInfo examples readability)
 - rust-lang#71485 (Add BinaryHeap::retain as suggested in rust-lang#42849)
 - rust-lang#71512 (Remove useless "" args)
 - rust-lang#71527 (Miscellaneous cleanup in `check_consts`)
 - rust-lang#71534 (Avoid unused Option::map results)
 - rust-lang#71535 (Fix typos in docs for keyword "in")

Failed merges:

r? @ghost
@mbrubeck mbrubeck changed the title Add retain() and drain() for BTreeMap, BTreeSet, BinaryHeap Add retain() and drain_filter() for BTreeMap, BTreeSet, BinaryHeap Jul 8, 2020
@mbrubeck mbrubeck changed the title Add retain() and drain_filter() for BTreeMap, BTreeSet, BinaryHeap Add drain_filter for BinaryHeap Sep 8, 2020
@mbrubeck
Copy link
Contributor

mbrubeck commented Sep 8, 2020

All but two of the methods originally requested here have since been implemented. I'm splitting this issue so that we have one ticket for per method. This ticket is for BinaryHeap::drain_filter.

BTreeMap/BTreeSet::drain_filter are tracked at #70530. BinaryHeap::retain is tracked at #71503. BTreeMap/BTreeSet::retain are part of rust-lang/rfcs#1338.

@inquisitivecrystal
Copy link
Contributor

Should BinaryHeap::drain_filter be sorted or not? BinaryHeap::drain isn't sorted, but there's an equivalent, BinaryHeap::drain_sorted, which is.

@mikeleany
Copy link
Contributor

@rustbot claim

@dis-da-moe
Copy link

@rustbot claim

@dis-da-moe
Copy link

dis-da-moe commented Nov 13, 2022

Some questions from implementing this feature:

  1. Should the closure also accept an &mut T? An item could be mutated to violate the heap order. Two possible solutions:
    1. Change the closure to accept an & T. This would mean one less feature and make this implementation inconsistent with others. But it would avoid the complexity of 2.
    2. Change the closure to accept a struct that behaves similarly to PeekMut<T>. If the struct is deref'd mut to an &mut T then on drop it will ensure the item is sorted correctly on the heap. This increases potential complexity in implementation and for the end user, as instead of accessing the value directly they need to deref it.
  2. Should the items be given to the closure in order or out of order? Or should we follow the route of drain and have drain_filter and drain_filter_sorted?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-collections Area: std::collections. C-feature-accepted Category: A feature request that has been accepted pending implementation. E-help-wanted Call for participation: Help is requested to fix this issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.