diff --git a/pkg/xmap/README.md b/pkg/xmap/README.md
index 06cbf93..5e6e50d 100644
--- a/pkg/xmap/README.md
+++ b/pkg/xmap/README.md
@@ -14,10 +14,15 @@ import "github.com/dashjay/xiter/pkg/xmap"
- [func Equal\[M1, M2 \~map\[K\]V, K, V comparable\]\(m1 M1, m2 M2\) bool](<#Equal>)
- [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 Find\[K comparable, V any\]\(in map\[K\]V, fn func\(K, V\) bool\) \(K, V, bool\)](<#Find>)
+- [func FindKey\[K comparable, V any\]\(in map\[K\]V, target K\) \(K, V, bool\)](<#FindKey>)
+- [func FindKeyO\[K comparable, V any\]\(in map\[K\]V, target K\) optional.O\[union.U2\[K, V\]\]](<#FindKeyO>)
+- [func FindO\[K comparable, V any\]\(in map\[K\]V, fn func\(K, V\) bool\) optional.O\[union.U2\[K, V\]\]](<#FindO>)
- [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 ToXSyncMap\[K comparable, V any\]\(in map\[K\]V\) \*xsync.SyncMap\[K, V\]](<#ToXSyncMap>)
- [func Values\[M \~map\[K\]V, K comparable, V any\]\(m M\) \[\]V](<#Values>)
@@ -31,7 +36,7 @@ func Clone[M ~map[K]V, K comparable, V any](m M) M
-## func [CoalesceMaps]()
+## func [CoalesceMaps]()
```go
func CoalesceMaps[M ~map[K]V, K comparable, V any](maps ...M) M
@@ -93,7 +98,7 @@ func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M
-## func [Filter]()
+## func [Filter]()
```go
func Filter[M ~map[K]V, K comparable, V any](in M, fn func(K, V) bool) M
@@ -110,6 +115,42 @@ result := Filter(m, fn)
// result will be map[string]int{"b": 2, "c": 3}
```
+
+## func [Find]()
+
+```go
+func Find[K comparable, V any](in map[K]V, fn func(K, V) bool) (K, V, bool)
+```
+
+
+
+
+## func [FindKey]()
+
+```go
+func FindKey[K comparable, V any](in map[K]V, target K) (K, V, bool)
+```
+
+
+
+
+## func [FindKeyO]()
+
+```go
+func FindKeyO[K comparable, V any](in map[K]V, target K) optional.O[union.U2[K, V]]
+```
+
+
+
+
+## func [FindO]()
+
+```go
+func FindO[K comparable, V any](in map[K]V, fn func(K, V) bool) optional.O[union.U2[K, V]]
+```
+
+
+
## func [Keys]()
@@ -120,7 +161,7 @@ func Keys[M ~map[K]V, K comparable, V any](m M) []K
-## func [MapKeys]()
+## func [MapKeys]()
```go
func MapKeys[K comparable, V1 any](in map[K]V1, fn func(K, V1) K) map[K]V1
@@ -153,7 +194,7 @@ result := MapKeys(m, fn)
```
-## func [MapValues]()
+## func [MapValues]()
```go
func MapValues[K comparable, V1, V2 any](in map[K]V1, fn func(K, V1) V2) map[K]V2
@@ -194,6 +235,27 @@ func ToUnionSlice[M ~map[K]V, K comparable, V any](m M) []union.U2[K, V]
+
+## func [ToXSyncMap]()
+
+```go
+func ToXSyncMap[K comparable, V any](in map[K]V) *xsync.SyncMap[K, V]
+```
+
+ToXSyncMap converts a map to a xsync.SyncMap.
+
+Parameters:
+
+```
+in map[K]V: The input map to convert
+```
+
+Returns:
+
+```
+*xsync.SyncMap[K, V]: A new xsync.SyncMap containing the same key-value pairs as the input map
+```
+
## func [Values]()
diff --git a/pkg/xmap/xmap_common.go b/pkg/xmap/xmap_common.go
index 9798227..5519407 100644
--- a/pkg/xmap/xmap_common.go
+++ b/pkg/xmap/xmap_common.go
@@ -1,7 +1,10 @@
package xmap
import (
+ "github.com/dashjay/xiter/pkg/optional"
+ "github.com/dashjay/xiter/pkg/union"
"github.com/dashjay/xiter/pkg/xiter"
+ "github.com/dashjay/xiter/pkg/xsync"
)
// CoalesceMaps combines multiple maps into a single map. When duplicate keys are encountered,
@@ -96,3 +99,57 @@ func MapValues[K comparable, V1, V2 any](in map[K]V1, fn func(K, V1) V2) map[K]V
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)))
}
+
+// ToXSyncMap converts a map to a xsync.SyncMap.
+//
+// Parameters:
+//
+// in map[K]V: The input map to convert
+//
+// Returns:
+//
+// *xsync.SyncMap[K, V]: A new xsync.SyncMap containing the same key-value pairs as the input map
+func ToXSyncMap[K comparable, V any](in map[K]V) *xsync.SyncMap[K, V] {
+ m := xsync.NewSyncMap[K, V]()
+ for k, v := range in {
+ m.Store(k, v)
+ }
+ return m
+}
+
+func FindKey[K comparable, V any](in map[K]V, target K) (K, V, bool) {
+ v, ok := in[target]
+ if ok {
+ return target, v, ok
+ }
+ var zero K
+ return zero, v, ok
+}
+
+func FindKeyO[K comparable, V any](in map[K]V, target K) optional.O[union.U2[K, V]] {
+ v, ok := in[target]
+ if ok {
+ return optional.FromValue(union.U2[K, V]{T1: target, T2: v})
+ }
+ return optional.Empty[union.U2[K, V]]()
+}
+
+func Find[K comparable, V any](in map[K]V, fn func(K, V) bool) (K, V, bool) {
+ for k, v := range in {
+ if fn(k, v) {
+ return k, v, true
+ }
+ }
+ var k K
+ var v V
+ return k, v, false
+}
+
+func FindO[K comparable, V any](in map[K]V, fn func(K, V) bool) optional.O[union.U2[K, V]] {
+ for k, v := range in {
+ if fn(k, v) {
+ return optional.FromValue(union.U2[K, V]{T1: k, T2: v})
+ }
+ }
+ return optional.Empty[union.U2[K, V]]()
+}
diff --git a/pkg/xmap/xmap_test.go b/pkg/xmap/xmap_test.go
index a5bcd6c..1c43a47 100644
--- a/pkg/xmap/xmap_test.go
+++ b/pkg/xmap/xmap_test.go
@@ -132,7 +132,52 @@ func TestMap(t *testing.T) {
emptyMap := map[string]int{}
emptyResult := xmap.MapKeys(emptyMap, fn)
assert.Equal(t, map[string]int{}, emptyResult)
-
})
+ t.Run("to xsync-map", func(t *testing.T) {
+ m := xmap.ToXSyncMap(_map(0, 100))
+ assert.Equal(t, 100, m.Len())
+ })
+
+ t.Run("xmap find", func(t *testing.T) {
+ k, _, ok := xmap.Find(_map(0, 100), func(k int, v string) bool {
+ return k == 50
+ })
+ assert.Equal(t, 50, k)
+ assert.True(t, ok)
+
+ res := xmap.FindO(_map(0, 100), func(k int, v string) bool {
+ return k == 50
+ })
+ assert.Equal(t, 50, res.Must().T1)
+ assert.True(t, res.Ok())
+
+ k, _, ok = xmap.FindKey(_map(0, 100), 50)
+ assert.Equal(t, 50, k)
+ assert.True(t, ok)
+
+ res = xmap.FindKeyO(_map(0, 100), 50)
+ assert.Equal(t, 50, res.Must().T1)
+ assert.True(t, res.Ok())
+
+ // can not find
+ k, _, ok = xmap.Find(_map(0, 100), func(k int, v string) bool {
+ return k == 100
+ })
+ assert.Equal(t, 0, k)
+ assert.False(t, ok)
+
+ res = xmap.FindO(_map(0, 100), func(k int, v string) bool {
+ return k == 100
+ })
+ assert.False(t, res.Ok())
+
+ k, _, ok = xmap.FindKey(_map(0, 100), 100)
+ assert.Equal(t, 0, k)
+ assert.False(t, ok)
+
+ res = xmap.FindKeyO(_map(0, 100), 100)
+ assert.False(t, res.Ok())
+
+ })
}