From 069812e0eee1b9e462ca3cc6cfc6d51ca94563fe Mon Sep 17 00:00:00 2001 From: donutloop Date: Tue, 27 Feb 2024 03:36:26 +0100 Subject: [PATCH] Hashmap: Add FilterByValue (#184) The FilterByValue function is a method defined on the HashMap type. It generates a new HashMap containing only the elements that satisfy a specified condition, as determined by a predicate function applied to each element's value. Note: Will add later doc --- datastructure/hashmap/hashmap.go | 24 ++++++++++++++++++++++++ datastructure/hashmap/hashmap_test.go | 21 +++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/datastructure/hashmap/hashmap.go b/datastructure/hashmap/hashmap.go index d754476..b8e7f3d 100644 --- a/datastructure/hashmap/hashmap.go +++ b/datastructure/hashmap/hashmap.go @@ -123,6 +123,25 @@ func (hm *HashMap) Iterate(iteratee func(key, value any)) { } } +// FilterByValue returns a filtered HashMap. +// If any value is not matching the perdicate function then it returns nil +// otherwise it returns the HashMap with selected values. +func (hm *HashMap) FilterByValue(perdicate func(value any) bool) *HashMap { + var filteredHM *HashMap + if hm.size > 0 { + for i := 0; i < len(hm.table); i++ { + item := hm.table[i] + if item != nil && perdicate(item.value) { + if filteredHM == nil { + filteredHM = NewHashMap() + } + filteredHM.Put(item.key, item.value) + } + } + } + return filteredHM +} + // Keys returns a slice of the hashmap's keys (random order) func (hm *HashMap) Keys() []any { keys := make([]any, int(hm.size)) @@ -168,6 +187,11 @@ func (hm *HashMap) resize() { } } +// Size returns current size of Hashmap +func (hm *HashMap) Size() uint64 { + return hm.size +} + func (hm *HashMap) hash(key any) uint64 { h := fnv.New64a() _, _ = h.Write([]byte(fmt.Sprintf("%v", key))) diff --git a/datastructure/hashmap/hashmap_test.go b/datastructure/hashmap/hashmap_test.go index 747af19..66ebe2b 100644 --- a/datastructure/hashmap/hashmap_test.go +++ b/datastructure/hashmap/hashmap_test.go @@ -105,3 +105,24 @@ func TestHashMap_GetOrDefault(t *testing.T) { assert.Equal(1, hm.GetOrDefault("a", 5)) assert.Equal(5, hm.GetOrDefault("d", 5)) } + +func TestHashMap_FilterByValue(t *testing.T) { + t.Parallel() + + assert := internal.NewAssert(t, "TestHashMap_FilterByValue") + + hm := NewHashMap() + + hm.Put("a", 1) + hm.Put("b", 2) + hm.Put("c", 3) + hm.Put("d", 4) + hm.Put("e", 5) + hm.Put("f", 6) + + filteredHM := hm.FilterByValue(func(value any) bool { + return value.(int) == 1 || value.(int) == 3 + }) + + assert.Equal(uint64(2), filteredHM.Size()) +}