diff --git a/pkg/xmap/README.md b/pkg/xmap/README.md
index cc9094a..06cbf93 100644
--- a/pkg/xmap/README.md
+++ b/pkg/xmap/README.md
@@ -15,6 +15,8 @@ import "github.com/dashjay/xiter/pkg/xmap"
- [func EqualFunc\[M1 \~map\[K\]V1, M2 \~map\[K\]V2, K comparable, V1, V2 any\]\(m1 M1, m2 M2, eq func\(V1, V2\) bool\) bool](<#EqualFunc>)
- [func Filter\[M \~map\[K\]V, K comparable, V any\]\(in M, fn func\(K, V\) bool\) M](<#Filter>)
- [func Keys\[M \~map\[K\]V, K comparable, V any\]\(m M\) \[\]K](<#Keys>)
+- [func MapKeys\[K comparable, V1 any\]\(in map\[K\]V1, fn func\(K, V1\) K\) map\[K\]V1](<#MapKeys>)
+- [func MapValues\[K comparable, V1, V2 any\]\(in map\[K\]V1, fn func\(K, V1\) V2\) map\[K\]V2](<#MapValues>)
- [func ToUnionSlice\[M \~map\[K\]V, K comparable, V any\]\(m M\) \[\]union.U2\[K, V\]](<#ToUnionSlice>)
- [func Values\[M \~map\[K\]V, K comparable, V any\]\(m M\) \[\]V](<#Values>)
@@ -117,6 +119,72 @@ func Keys[M ~map[K]V, K comparable, V any](m M) []K
+
+## func [MapKeys]()
+
+```go
+func MapKeys[K comparable, V1 any](in map[K]V1, fn func(K, V1) K) map[K]V1
+```
+
+MapKeys transforms the keys of a map using the provided function while keeping values unchanged. This is useful for transforming data structures while preserving the value associations.
+
+Parameters:
+
+```
+in map[K]V1: The input map to transform
+fn func(K, V1) K: A function that takes a key and its corresponding value, and returns a new key
+```
+
+Returns:
+
+```
+map[K]V1: A new map with the same values as the input map but with transformed keys
+```
+
+Example:
+
+```
+m := map[string]int{"a": 1, "b": 2, "c": 3}
+fn := func(k string, v int) string {
+ return k + "_key"
+}
+result := MapKeys(m, fn)
+// result will be map[string]int{"a_key": 1, "b_key": 2, "c_key": 3}
+```
+
+
+## func [MapValues]()
+
+```go
+func MapValues[K comparable, V1, V2 any](in map[K]V1, fn func(K, V1) V2) map[K]V2
+```
+
+MapValues transforms the values of a map using the provided function while keeping keys unchanged. This is useful for transforming data structures while preserving the key associations.
+
+Parameters:
+
+```
+in M: The input map to transform
+fn func(K, V1) V2: A function that takes a key and its corresponding value, and returns a new value
+```
+
+Returns:
+
+```
+map[K]V2: A new map with the same keys as the input map but with transformed values
+```
+
+Example:
+
+```
+m := map[string]int{"a": 1, "b": 2, "c": 3}
+fn := func(k string, v int) string {
+ return fmt.Sprintf("value_%d", v)
+}
+result := MapValues(m, fn)
+// result will be map[string]string{"a": "value_1", "b": "value_2", "c": "value_3"}
+```
+
## func [ToUnionSlice]()
diff --git a/pkg/xmap/xmap_common.go b/pkg/xmap/xmap_common.go
index b2261b0..9798227 100644
--- a/pkg/xmap/xmap_common.go
+++ b/pkg/xmap/xmap_common.go
@@ -48,3 +48,51 @@ func CoalesceMaps[M ~map[K]V, K comparable, V any](maps ...M) M {
func Filter[M ~map[K]V, K comparable, V any](in M, fn func(K, V) bool) M {
return xiter.ToMap(xiter.Filter2(fn, xiter.FromMapKeyAndValues(in)))
}
+
+// MapValues transforms the values of a map using the provided function while keeping keys unchanged.
+// This is useful for transforming data structures while preserving the key associations.
+//
+// Parameters:
+//
+// in M: The input map to transform
+// fn func(K, V1) V2: A function that takes a key and its corresponding value, and returns a new value
+//
+// Returns:
+//
+// map[K]V2: A new map with the same keys as the input map but with transformed values
+//
+// Example:
+//
+// m := map[string]int{"a": 1, "b": 2, "c": 3}
+// fn := func(k string, v int) string {
+// return fmt.Sprintf("value_%d", v)
+// }
+// result := MapValues(m, fn)
+// // result will be map[string]string{"a": "value_1", "b": "value_2", "c": "value_3"}
+func MapValues[K comparable, V1, V2 any](in map[K]V1, fn func(K, V1) V2) map[K]V2 {
+ return xiter.ToMap(xiter.Map2(func(k K, v V1) (K, V2) { return k, fn(k, v) }, xiter.FromMapKeyAndValues(in)))
+}
+
+// MapKeys transforms the keys of a map using the provided function while keeping values unchanged.
+// This is useful for transforming data structures while preserving the value associations.
+//
+// Parameters:
+//
+// in map[K]V1: The input map to transform
+// fn func(K, V1) K: A function that takes a key and its corresponding value, and returns a new key
+//
+// Returns:
+//
+// map[K]V1: A new map with the same values as the input map but with transformed keys
+//
+// Example:
+//
+// m := map[string]int{"a": 1, "b": 2, "c": 3}
+// fn := func(k string, v int) string {
+// return k + "_key"
+// }
+// result := MapKeys(m, fn)
+// // result will be map[string]int{"a_key": 1, "b_key": 2, "c_key": 3}
+func MapKeys[K comparable, V1 any](in map[K]V1, fn func(K, V1) K) map[K]V1 {
+ return xiter.ToMap(xiter.Map2(func(k K, v V1) (K, V1) { return fn(k, v), v }, xiter.FromMapKeyAndValues(in)))
+}
diff --git a/pkg/xmap/xmap_test.go b/pkg/xmap/xmap_test.go
index 8417659..a5bcd6c 100644
--- a/pkg/xmap/xmap_test.go
+++ b/pkg/xmap/xmap_test.go
@@ -87,4 +87,52 @@ func TestMap(t *testing.T) {
result := xmap.Filter(m, fn)
assert.True(t, xmap.Equal(result, _map(51, 100)))
})
+
+ t.Run("map values", func(t *testing.T) {
+ m := map[string]int{"a": 1, "b": 2, "c": 3}
+ fn := func(k string, v int) string {
+ return fmt.Sprintf("value_%d", v)
+ }
+ var result = xmap.MapValues(m, fn)
+ expected := map[string]string{"a": "value_1", "b": "value_2", "c": "value_3"}
+ assert.Equal(t, expected, result)
+
+ // Test with key usage in transformation
+ fnWithKey := func(k string, v int) string {
+ return fmt.Sprintf("%s_%d", k, v)
+ }
+ resultWithKey := xmap.MapValues(m, fnWithKey)
+ expectedWithKey := map[string]string{"a": "a_1", "b": "b_2", "c": "c_3"}
+ assert.Equal(t, expectedWithKey, resultWithKey)
+
+ // Test with empty map
+ emptyMap := map[string]int{}
+ emptyResult := xmap.MapValues(emptyMap, fn)
+ assert.Equal(t, map[string]string{}, emptyResult)
+ })
+
+ t.Run("map keys", func(t *testing.T) {
+ m := map[string]int{"a": 1, "b": 2, "c": 3}
+ fn := func(k string, v int) string {
+ return k + "_key"
+ }
+ var result = xmap.MapKeys(m, fn)
+ expected := map[string]int{"a_key": 1, "b_key": 2, "c_key": 3}
+ assert.Equal(t, expected, result)
+
+ // Test with value usage in transformation
+ fnWithValue := func(k string, v int) string {
+ return fmt.Sprintf("%s_%d", k, v)
+ }
+ resultWithValue := xmap.MapKeys(m, fnWithValue)
+ expectedWithValue := map[string]int{"a_1": 1, "b_2": 2, "c_3": 3}
+ assert.Equal(t, expectedWithValue, resultWithValue)
+
+ // Test with empty map
+ emptyMap := map[string]int{}
+ emptyResult := xmap.MapKeys(emptyMap, fn)
+ assert.Equal(t, map[string]int{}, emptyResult)
+
+ })
+
}