Bug 4271 – drop/pop methods for std.algorithm.BinaryHeap

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2010-06-04T15:28:00Z
Last change time
2017-08-08T11:14:41Z
Keywords
trivial
Assigned to
andrei
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2010-06-04T15:28:50Z
During the usage of a Heap one of the most commonly used operations is to pop an item from a heap and then to use it. But in std.algorithm.BinaryHeap the pop() doesn't return the item, probably for performance reasons (it requires the copy of the item). (So to pop an use one item you can use pop(1)[0] or take the top and then pop, but the second possibility is not an expression.) There are some ways to solve this problem, but the simpler is probably to just use two different names for two functions. So the pop() can return the popped item. And then the heap can define another method that just pops the top item and doesn't return it, this method can be called for example "drop". The following untested code gives is an idea of how it can be implemented: /** Pops the largest element (according to the predicate $(D less)) and returns it. */ ElementType!Range pop() { enforce(_length); auto tmp = _store.front; enforce(_length); if (_length > 1) swap(_store.front, _store[_length - 1]); --_length; percolateDown(_store[0 .. _length]); return tmp; } /** Drops the largest element (according to the predicate $(D less)). */ void drop() { enforce(_length); if (_length > 1) swap(_store.front, _store[_length - 1]); --_length; percolateDown(_store[0 .. _length]); }
Comment #1 by andrei — 2010-06-04T15:30:36Z
What's wrong with top()?
Comment #2 by bearophile_hugs — 2010-06-04T15:40:21Z
In most of my usages of a heap I don't have just to use the top item or just to pop the top item, I have to pop the top item and then use the popped out item. To perform this operation I can currently use something like: item = heap.top(); heap.pop(); But this is not handy because that is not a single expression, so I can't put it inside other expressions. So I have to use: somefunction(heap.top(1)[0]); But being this operation so common, I'd like to write simpler code: somefunction(heap.top()); I have suggested to add the drop() method too to not decrease the performance of the (uncommon) code that just needs to remove the top item with no need to use it (or uses it using top() in other points of the code).
Comment #3 by bearophile_hugs — 2010-06-04T16:00:04Z
Sorry, that was a partially wrong comment, I meant: So I have to use: somefunction(heap.pop(1)[0]); But being this operation so common, I'd like to write simpler code: somefunction(heap.pop());
Comment #4 by greeenify — 2016-12-23T18:55:52Z
Imho this is a common problem of the range API and I would love to see a generic solution. For prior art see e.g. https://github.com/dlang/phobos/pull/4010 and a good, generic solution in phobos-next that checks as a constraint whether it's valid to do the move: https://github.com/nordlow/phobos-next/blob/master/src/range_ex.d#L57
Comment #5 by razvan.nitu1305 — 2017-08-08T11:14:41Z
It seems that meanwhile, binaryHeap has been moved from std.algorithm to std.container and the method removeAny [1] was added which does exactly what this bug report asks for. Closing as fixed. [1] http://dlang.org/phobos/std_container_binaryheap.html#.BinaryHeap.removeAny