Skip to content

Commit 7cb9a2c

Browse files
committed
Add Heap.removeAll(where:)
1 parent 78b544f commit 7cb9a2c

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

Sources/HeapModule/Heap.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,30 @@ extension Heap {
268268
_checkInvariants()
269269
return removed
270270
}
271+
272+
/// Removes all the elements that satisfy the given predicate.
273+
///
274+
/// The heap *must not* be empty.
275+
///
276+
/// - Parameter shouldBeRemoved: A closure that takes an element of the
277+
/// heap as its argument and returns a Boolean value indicating
278+
/// whether the element should be removed from the heap.
279+
///
280+
/// - Complexity: O(*n*), where *n* is the number of items in the heap.
281+
@inlinable
282+
public mutating func removeAll(
283+
where shouldBeRemoved: (Element) throws -> Bool
284+
) rethrows {
285+
// Precondition: the heap must not be empty.
286+
precondition(!isEmpty, "Heap must not be empty")
287+
_storage = try _storage.filter { try !shouldBeRemoved($0) }
288+
if _storage.count > 1 {
289+
_update { handle in
290+
handle.heapify()
291+
}
292+
}
293+
_checkInvariants()
294+
}
271295

272296
/// Replaces the maximum value in the heap with the given replacement,
273297
/// then updates heap contents to reflect the change.

Tests/HeapTests/HeapTests.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,4 +587,24 @@ final class HeapTests: CollectionTestCase {
587587
}
588588
}
589589
}
590+
591+
func test_removeAll_noneRemoved() {
592+
var heap = Heap<Int>((1...10).shuffled())
593+
let originalSorted = heap.unordered.sorted()
594+
heap.removeAll { _ in false }
595+
expectEqualElements(heap.itemsInAscendingOrder(), originalSorted)
596+
}
597+
598+
func test_removeAll_allRemoved() {
599+
var heap = Heap<Int>((1...10).shuffled())
600+
heap.removeAll { _ in true }
601+
expectTrue(heap.isEmpty)
602+
}
603+
604+
func test_removeAll_removeEvenNumbers() {
605+
var heap = Heap<Int>((1...10).shuffled())
606+
heap.removeAll { $0 % 2 == 0 }
607+
let expected = (1...10).filter { $0 % 2 != 0 }.sorted()
608+
expectEqualElements(heap.itemsInAscendingOrder(), expected)
609+
}
590610
}

0 commit comments

Comments
 (0)