Skip to content

Commit

Permalink
feat: adding FindKey and FindKeyBy
Browse files Browse the repository at this point in the history
  • Loading branch information
samber committed Jul 3, 2022
1 parent f1f9d18 commit 5bdd1c1
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 1 deletion.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@

@samber: I sometimes forget to update this file. Ping me on [Twitter](https://twitter.com/samuelberthe) or open an issue in case of error. We need to keep a clear changelog for easier lib upgrade.

## 1.22.0 (2022-07-03)
## 1.23.0 (2022-07-04)

Adding:

- lo.FindKey
- lo.FindKeyBy

## 1.22.0 (2022-07-04)

Adding:

Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ Supported search helpers:
- Find
- FindIndexOf
- FindLastIndexOf
- FindKey
- FindKeyBy
- Min
- MinBy
- Max
Expand Down Expand Up @@ -1158,6 +1160,40 @@ str, index, ok := lo.FindLastIndexOf[string]([]string{"foobar"}, func(i string)
// "", -1, false
```

### FindKey

Returns the key of the first value matching.

```go
result1, ok1 := lo.FindKey(map[string]int{"foo": 1, "bar": 2, "baz": 3}, 2)
// "bar", true

result2, ok2 := lo.FindKey(map[string]int{"foo": 1, "bar": 2, "baz": 3}, 42)
// "", false

type test struct {
foobar string
}
result3, ok3 := lo.FindKey(map[string]test{"foo": test{"foo"}, "bar": test{"bar"}, "baz": test{"baz"}}, test{"foo"})
// "foo", true
```

### FindKeyBy

Returns the key of the first element predicate returns truthy for.

```go
result1, ok1 := lo.FindKeyBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
return k == "foo"
})
// "foo", true

result2, ok2 := lo.FindKeyBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
return false
})
// "", false
```

### Min

Search the minimum value of a collection.
Expand Down
22 changes: 22 additions & 0 deletions find.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,28 @@ func FindOrElse[T any](collection []T, fallback T, predicate func(T) bool) T {
return fallback
}

// FindKey returns the key of the first value matching.
func FindKey[K comparable, V comparable](object map[K]V, value V) (K, bool) {
for k, v := range object {
if v == value {
return k, true
}
}

return Empty[K](), false
}

// FindKeyBy returns the key of the first element predicate returns truthy for.
func FindKeyBy[K comparable, V comparable](object map[K]V, predicate func(K, V) bool) (K, bool) {
for k, v := range object {
if predicate(k, v) {
return k, true
}
}

return Empty[K](), false
}

// Min search the minimum value of a collection.
func Min[T constraints.Ordered](collection []T) T {
var min T
Expand Down
40 changes: 40 additions & 0 deletions find_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,46 @@ func TestFindOrElse(t *testing.T) {
is.Equal(result2, "x")
}

func TestFindKey(t *testing.T) {
is := assert.New(t)

result1, ok1 := FindKey(map[string]int{"foo": 1, "bar": 2, "baz": 3}, 2)
is.Equal("bar", result1)
is.True(ok1)

result2, ok2 := FindKey(map[string]int{"foo": 1, "bar": 2, "baz": 3}, 42)
is.Equal("", result2)
is.False(ok2)

type test struct {
foobar string
}

result3, ok3 := FindKey(map[string]test{"foo": test{"foo"}, "bar": test{"bar"}, "baz": test{"baz"}}, test{"foo"})
is.Equal("foo", result3)
is.True(ok3)

result4, ok4 := FindKey(map[string]test{"foo": test{"foo"}, "bar": test{"bar"}, "baz": test{"baz"}}, test{"hello world"})
is.Equal("", result4)
is.False(ok4)
}

func TestFindKeyBy(t *testing.T) {
is := assert.New(t)

result1, ok1 := FindKeyBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
return k == "foo"
})
is.Equal("foo", result1)
is.True(ok1)

result2, ok2 := FindKeyBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
return false
})
is.Equal("", result2)
is.False(ok2)
}

func TestMin(t *testing.T) {
is := assert.New(t)

Expand Down

0 comments on commit 5bdd1c1

Please sign in to comment.