Skip to content

Commit 9454599

Browse files
committed
fix: .iterator() method follows Java's PriorityQueue implementation
1 parent d8fba99 commit 9454599

10 files changed

+125
-87
lines changed

README.md

+18-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ heap vs array: push + top(50) of 100
4040

4141
## Changelog
4242

43+
### 2.2
44+
45+
- Fixes `.iterator()` method to follow [Java's PriorityQueue implementation:
46+
](https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html)
47+
> The Iterator provided in method [iterator()](<https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html#iterator()>) is not guaranteed to traverse the elements of the priority queue in any particular order.
48+
49+
Notice that _using the heap directly as an iteraror will consume the heap,_ as Python's `heapq` implementation does.
50+
4351
### 2.1
4452

4553
- Adds `Heap.nlargest` as heapq.
@@ -77,7 +85,7 @@ console.log(minHeap.peek()); //> 1
7785
console.log(minHeap.pop()); //> 1
7886
console.log(minHeap.peek()); //> 2
7987

80-
// Iterator
88+
// Iterator, that will consume the heap
8189
maxHeap.init([3, 4, 1, 12, 8]);
8290
for (const value of maxHeap) {
8391
console.log('Next top value is', value);
@@ -94,7 +102,13 @@ const customPriorityComparator = (a, b) => a.priority - b.priority;
94102
const priorityQueue = new Heap(customPriorityComparator);
95103
priorityQueue.init(tasks);
96104

97-
// priorityQueue === priorityQueue.iterator()
105+
// Iterator, the Java way, that will not consume the heap but does not guarantee
106+
// to traverse the elements of the heap in any particular order. Barely useful.
107+
for (const taks of priorityQueue.iterator()) {
108+
// Do something
109+
}
110+
111+
// Iterator, the JavaScript and Python way, that will consume the heap
98112
for (const task of priorityQueue) {
99113
// Do something
100114
}
@@ -133,6 +147,7 @@ Basic comparators already included:
133147

134148
## Implements JavaScript style methods
135149

150+
- `for (const value of heap)` directly usable as an Iterator, consumes the heap
136151
- `length` of the heap
137152
- `limit` amount of elements in the heap
138153
- `pop()` the top element
@@ -152,7 +167,7 @@ Basic comparators already included:
152167
- `contains(element, fn?)`
153168
- _`element()` alias of `peek()`_
154169
- `isEmpty()`
155-
- `iterator()` returns `this` because it is iterable
170+
- `iterator()` returns the same as `toArray()` because it is iterable and follows Java's implementation
156171
- _`offer(element)` alias of `add(element)`_
157172
- `peek()`
158173
- _`poll()` alias of `pop()`_

dist/heap-js.es5.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ var Heap = /** @class */ (function () {
693693
* Returns an iterator. To comply with Java interface.
694694
*/
695695
Heap.prototype.iterator = function () {
696-
return this;
696+
return this.toArray();
697697
};
698698
/**
699699
* Limit heap size if needed

dist/heap-js.umd.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@
699699
* Returns an iterator. To comply with Java interface.
700700
*/
701701
Heap.prototype.iterator = function () {
702-
return this;
702+
return this.toArray();
703703
};
704704
/**
705705
* Limit heap size if needed

docs/assets/main.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/assets/style.css

+3-2
Original file line numberDiff line numberDiff line change
@@ -766,12 +766,13 @@ footer .tsd-legend {
766766

767767
.tsd-flag {
768768
display: inline-block;
769-
padding: 1px 5px;
769+
padding: 0.25em 0.4em;
770770
border-radius: 4px;
771771
color: var(--color-comment-tag-text);
772772
background-color: var(--color-comment-tag);
773773
text-indent: 0;
774-
font-size: 14px;
774+
font-size: 75%;
775+
line-height: 1;
775776
font-weight: normal;
776777
}
777778

docs/classes/Heap.html

+63-63
Large diffs are not rendered by default.

docs/index.html

+17-4
Large diffs are not rendered by default.

docs/modules.html

+1-1
Large diffs are not rendered by default.

src/Heap.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ export class Heap<T> implements Iterable<T> {
646646
* Returns an iterator. To comply with Java interface.
647647
*/
648648
iterator(): Iterable<T> {
649-
return this;
649+
return this.toArray();
650650
}
651651

652652
/**

tests/heap-public-methods.test.ts

+18-9
Original file line numberDiff line numberDiff line change
@@ -425,27 +425,36 @@ describe('Heap instances', function () {
425425
});
426426

427427
describe('is Iterable', function () {
428-
it('should be iterable via for...of', function () {
428+
it('should be iterable via for...of, consuming the heap', function () {
429429
heap.init(values.concat(values));
430430
const top = heap.toArray().slice(0);
431431
top.sort(heap.comparator());
432-
const result = [];
432+
const resultFirstRound = [];
433433
for (const value of heap) {
434-
result.push(value);
434+
resultFirstRound.push(value);
435435
}
436-
expect(result).toEqual(top);
436+
const resultSecondRound = [];
437+
for (const value of heap) {
438+
resultSecondRound.push(value);
439+
}
440+
expect(resultFirstRound).toEqual(top);
441+
expect(resultSecondRound).toEqual([]);
437442
});
438443
});
439444
describe('#iterator()', function () {
440-
it('returns an iterable', function () {
445+
it('returns an iterable that does not consume the heap', function () {
441446
heap.init(values.concat(values));
442447
const top = heap.toArray().slice(0);
443-
top.sort(heap.comparator());
444-
const result = [];
448+
const resultFirstRound = [];
449+
for (const value of heap.iterator()) {
450+
resultFirstRound.push(value);
451+
}
452+
const resultSecondRound = [];
445453
for (const value of heap.iterator()) {
446-
result.push(value);
454+
resultSecondRound.push(value);
447455
}
448-
expect(result).toEqual(top);
456+
expect(resultFirstRound).toEqual(top);
457+
expect(resultSecondRound).toEqual(top);
449458
});
450459
});
451460
});

0 commit comments

Comments
 (0)