X-Git-Url: http://nitlanguage.org diff --git a/lib/more_collections.nit b/lib/more_collections.nit index ac2c8d1..3062d5e 100644 --- a/lib/more_collections.nit +++ b/lib/more_collections.nit @@ -13,7 +13,9 @@ # limitations under the License. # Highly specific, but useful, collections-related classes. -module more_collections +module more_collections is serialize + +import serialization # Simple way to store an `HashMap[K, Array[V]]` # @@ -61,6 +63,7 @@ end # assert hm2[2, "not-two"] == null # ~~~~ class HashMap2[K1, K2, V] + private var level1 = new HashMap[K1, HashMap[K2, V]] # Return the value associated to the keys `k1` and `k2`. @@ -94,6 +97,13 @@ class HashMap2[K1, K2, V] level2.keys.remove(k2) end + # Is there a value at `k1, k2`? + fun has(k1: K1, k2: K2): Bool + do + if not level1.keys.has(k1) then return false + return level1[k1].keys.has(k2) + end + # Remove all items fun clear do level1.clear end @@ -108,6 +118,7 @@ end # assert hm3[2, "not-two", 22] == null # ~~~~ class HashMap3[K1, K2, K3, V] + private var level1 = new HashMap[K1, HashMap2[K2, K3, V]] # Return the value associated to the keys `k1`, `k2`, and `k3`. @@ -141,6 +152,13 @@ class HashMap3[K1, K2, K3, V] level2.remove_at(k2, k3) end + # Is there a value at `k1, k2, k3`? + fun has(k1: K1, k2: K2, k3: K3): Bool + do + if not level1.keys.has(k1) then return false + return level1[k1].has(k2, k3) + end + # Remove all items fun clear do level1.clear end @@ -522,3 +540,44 @@ private class UnrolledIterator[E] end end end + +# Keep track of the best elements according to a distance value. +# +# ~~~ +# var bests = new BestDistance[String](5) +# bests.update(10, "Too big") +# assert bests.best_items.is_empty +# bests.update(5, "Just fine") +# bests.update(5, "Another one") +# assert bests.best_items.has_exactly(["Just fine", "Another one"]) +# bests.update(2, "A better one") +# bests.update(4, "Not good enough") +# assert bests.best_distance == 2 +# assert bests.best_items.has_exactly(["A better one"]) +# ~~~ +class BestDistance[E] + # Current smallest distance + var best_distance: Int is writable + + # Known elements with the smallest distance + var best_items = new Set[E] is writable + + # Register a `candidate` with a `distance` + # + # * To high, it is ignored. + # * Equal to the current best, it is added + # * Better that them, is is the new best element + # + # Return `true` if the candidate is kept (alone or with other) + # returns `false` if the candidate is ignored. + fun update(distance: Int, candidate: E): Bool + do + if distance > best_distance then return false + if distance < best_distance then + best_distance = distance + best_items.clear + end + best_items.add candidate + return true + end +end