diff --git a/Ordered Set/OrderedSet.swift b/Ordered Set/OrderedSet.swift index 8b6df7d3e..850050098 100644 --- a/Ordered Set/OrderedSet.swift +++ b/Ordered Set/OrderedSet.swift @@ -16,7 +16,7 @@ public class OrderedSet { // O(n) public func insert(_ object: T, at index: Int) { - assert(index < objects.count, "Index should be smaller than object count") + assert(index <= objects.count, "Index should be smaller than object count") assert(index >= 0, "Index should be bigger than 0") guard indexOfKey[object] == nil else { @@ -73,5 +73,36 @@ public class OrderedSet { public func all() -> [T] { return objects } + + // convenience checker - minimize need for client's knowledge of internals + public func contains(_ object: T) ->Bool { + return indexOfKey[object] != nil + } + + // O(1) + // append object (removing any existing other occurrence) + public func ensure_at_end(_ object: T) { + if contains(object) { + remove(object) + } + add(object) + } + + // O(n) + // prepend object (removing any existing other occurrence) + public func ensure_at_front(_ object: T) { + if contains(object) { + remove(object) // could make this more efficient (at the expense of maintenance complexity) by not delegating to remove() and insert() + // but instead doing manually, and running for loop just once at end + } + insert(object, at:0) + } + + // string representation, useful for printing/debugging + public func debug_str() -> String { + var str = "OrderedSet: \n" + str += objects.map{"\($0)"}.joined(separator: ",") + return str + } }