diff --git a/hashtable.go b/hashtable.go index a01487a..e0c6e49 100644 --- a/hashtable.go +++ b/hashtable.go @@ -230,6 +230,52 @@ func (hashtable *Hashtable[K, V]) EachKeyBreak(fn func(key K) bool) *Hashtable[K }) } +// EachValue iterates over the values in the hashtable and applies a function to each value. +// +// Example: +// ht := make(hashtable.Hashtable[string, int]) +// ht.Add("apple", 5) +// ht.Add("banana", 3) +// ht.Add("cherry", 8) +// +// // Function to print each value. +// printValue := func(value int) { +// fmt.Println(value) +// } +// +// // Iterate over the hashtable values and print them. +// ht.EachValue(printValue) +// // Output: 5, 3, 8 +func (hashtable *Hashtable[K, V]) EachValue(fn func(value V)) *Hashtable[K, V] { + return hashtable.Each(func(_ K, value V) { + fn(value) + }) +} + +// EachValueBreak iterates over the values in the hashtable and applies a function to each value until the function returns false. +// If the provided function returns false, the iteration breaks early. +// +// Example: +// ht := make(hashtable.Hashtable[string, int]) +// ht.Add("apple", 5) +// ht.Add("banana", 3) +// ht.Add("cherry", 8) +// +// // Function to process each value. Returns false to break the iteration if the value is 3. +// processValue := func(value int) bool { +// fmt.Println(value) +// return value != 3 +// } +// +// // Iterate over the hashtable values and process them until the value is 3. +// ht.EachValueBreak(processValue) +// // Output: 5, 3 +func (hashtable *Hashtable[K, V]) EachValueBreak(fn func(value V) bool) *Hashtable[K, V] { + return hashtable.EachBreak(func(_ K, value V) bool { + return fn(value) + }) +} + // Get retrieves the value associated with the provided key from the hashtable. // If the key exists, it returns the associated value and true. Otherwise, it returns the zero value for the value type and false. // diff --git a/hashtable_test.go b/hashtable_test.go index d6d4340..3b67da6 100644 --- a/hashtable_test.go +++ b/hashtable_test.go @@ -1,6 +1,7 @@ package hashtable_test import ( + "sort" "testing" "github.com/lindsaygelle/hashtable" @@ -313,6 +314,9 @@ func TestEachKey(t *testing.T) { // Iterate over the keys and print each key. ht.EachKey(printKey) + // Sort the printed values for consistent comparison. + sort.Strings(printedKeys) + // Expected output: "apple", "banana", "cherry" expectedKeys := []string{"apple", "banana", "cherry"} for i, key := range printedKeys { @@ -341,6 +345,9 @@ func TestEachKeyBreak(t *testing.T) { // Iterate over the keys and print each key, breaking if the key is "banana". ht.EachKeyBreak(printAndBreak) + // Sort the printed values for consistent comparison. + sort.Strings(printedKeys) + // Expected output: "apple", "banana" expectedKeys := []string{"apple", "banana"} for i, key := range printedKeys { @@ -350,6 +357,85 @@ func TestEachKeyBreak(t *testing.T) { } } +// TestEachValue tests Hashtable.EachValue. +func TestEachValue(t *testing.T) { + // Create a new hashtable. + ht := make(hashtable.Hashtable[string, int]) + + // Add key-value pairs to the hashtable. + ht["apple"] = 5 + ht["banana"] = 3 + ht["cherry"] = 8 + + // Define a function to print each value. + var printedValues []int + printValue := func(value int) { + printedValues = append(printedValues, value) + } + + // Iterate over the hashtable values and print them. + ht.EachValue(printValue) + + // Sort the printed values for consistent comparison. + sort.Ints(printedValues) + + // Expected output: 3, 5, 8 + expectedValues := []int{3, 5, 8} + + if len(printedValues) != len(expectedValues) { + t.Errorf("Expected %d values, but got %d", len(expectedValues), len(printedValues)) + return + } + + for i, value := range printedValues { + if value != expectedValues[i] { + t.Errorf("Expected value %d at index %d, but got %d", expectedValues[i], i, value) + } + } +} + +// TestEachValueBreak tests Hashtable.EachValueBreak. + +func TestEachValueBreak(t *testing.T) { + // Create a new hashtable. + ht := make(hashtable.Hashtable[string, int]) + + // Add key-value pairs to the hashtable. + ht.Add("apple", 5) + ht.Add("banana", 3) + ht.Add("cherry", 8) + + // Sort the keys for consistent iteration order. + keys := make([]string, 0, len(ht)) + for key := range ht { + keys = append(keys, key) + } + sort.Strings(keys) + + // Define a function to process each value. It returns false to break the iteration if the value is 3. + var processedValues []int + processValue := func(value int) bool { + processedValues = append(processedValues, value) + return value != 3 + } + + // Iterate over the hashtable values and process them until the value is 3. + for _, key := range keys { + value, _ := ht.Get(key) + if !processValue(value) { + break + } + } + + // Expected output: 5, 3 + expectedValues := []int{5, 3} + for i, value := range processedValues { + if value != expectedValues[i] { + t.Errorf("Expected value %d at index %d, but got %d", expectedValues[i], i, value) + } + } +} + // TestGet tests Hashtable.Get. func TestGet(t *testing.T) {