Explorar el Código

AK: Add HashMap::remove_all_matching(predicate)

This removes all matching entries from a hash map in a single pass.
Andreas Kling hace 3 años
padre
commit
376e5ef912
Se han modificado 2 ficheros con 37 adiciones y 2 borrados
  1. 13 2
      AK/HashMap.h
  2. 24 0
      Tests/AK/TestHashMap.cpp

+ 13 - 2
AK/HashMap.h

@@ -74,6 +74,17 @@ public:
         return false;
     }
 
+    template<typename TUnaryPredicate>
+    void remove_all_matching(TUnaryPredicate predicate)
+    {
+        for (auto it = begin(); it != end();) {
+            if (predicate(it->key, it->value))
+                it = remove(it);
+            else
+                ++it;
+        }
+    }
+
     using HashTableType = HashTable<Entry, EntryTraits, IsOrdered>;
     using IteratorType = typename HashTableType::Iterator;
     using ConstIteratorType = typename HashTableType::ConstIterator;
@@ -180,9 +191,9 @@ public:
         return find(value) != end();
     }
 
-    void remove(IteratorType it)
+    IteratorType remove(IteratorType it)
     {
-        m_table.remove(it);
+        return m_table.remove(it);
     }
 
     V& ensure(const K& key)

+ 24 - 0
Tests/AK/TestHashMap.cpp

@@ -71,6 +71,30 @@ TEST_CASE(map_remove)
     EXPECT(number_to_string.find(2) != number_to_string.end());
 }
 
+TEST_CASE(remove_all_matching)
+{
+    HashMap<int, String> map;
+
+    map.set(1, "One");
+    map.set(2, "Two");
+    map.set(3, "Three");
+    map.set(4, "Four");
+
+    EXPECT_EQ(map.size(), 4u);
+
+    map.remove_all_matching([&](int key, String const& value) {
+        return key == 1 || value == "Two";
+    });
+
+    EXPECT_EQ(map.size(), 2u);
+    EXPECT(map.contains(3));
+    EXPECT(map.contains(4));
+
+    map.remove_all_matching([&](int, String const&) { return true; });
+
+    EXPECT(map.is_empty());
+}
+
 TEST_CASE(case_insensitive)
 {
     HashMap<String, int, CaseInsensitiveStringTraits> casemap;