Skip to content

Commit 64e89e4

Browse files
committed
Merge branch 'nicklaus-dev-nick-add-without-by'
2 parents 7166d51 + 4201d6e commit 64e89e4

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ Supported intersection helpers:
211211
- [Difference](#difference)
212212
- [Union](#union)
213213
- [Without](#without)
214+
- [WithoutBy](#withoutby)
214215
- [WithoutEmpty](#withoutempty)
215216
- [WithoutNth](#withoutnth)
216217

@@ -2198,6 +2199,39 @@ subset := lo.Without([]int{0, 2, 10}, 0, 1, 2, 3, 4, 5)
21982199
// []int{10}
21992200
```
22002201

2202+
### WithoutBy
2203+
2204+
Filters a slice by excluding elements whose extracted keys match any in the exclude list.
2205+
2206+
It returns a new slice containing only the elements whose keys are not in the exclude list.
2207+
2208+
2209+
```go
2210+
type struct User {
2211+
ID int
2212+
Name string
2213+
}
2214+
2215+
// original users
2216+
users := []User{
2217+
{ID: 1, Name: "Alice"},
2218+
{ID: 2, Name: "Bob"},
2219+
{ID: 3, Name: "Charlie"},
2220+
}
2221+
2222+
// extract function to get the user ID
2223+
getID := func(user User) int {
2224+
return user.ID
2225+
}
2226+
2227+
// exclude users with IDs 2 and 3
2228+
excludedIDs := []int{2, 3}
2229+
2230+
// filtering users
2231+
filteredUsers := lo.WithoutBy(users, getID, excludedIDs...)
2232+
// []User[{ID: 1, Name: "Alice"}]
2233+
```
2234+
22012235
### WithoutEmpty
22022236

22032237
Returns slice excluding zero values.

intersect.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,23 @@ func Without[T comparable, Slice ~[]T](collection Slice, exclude ...T) Slice {
181181
return result
182182
}
183183

184+
// WithoutBy filters a slice by excluding elements whose extracted keys match any in the exclude list.
185+
// It returns a new slice containing only the elements whose keys are not in the exclude list.
186+
func WithoutBy[T any, K comparable](collection []T, iteratee func(item T) K, exclude ...K) []T {
187+
excludeMap := make(map[K]struct{}, len(exclude))
188+
for _, e := range exclude {
189+
excludeMap[e] = struct{}{}
190+
}
191+
192+
result := make([]T, 0, len(collection))
193+
for _, item := range collection {
194+
if _, ok := excludeMap[iteratee(item)]; !ok {
195+
result = append(result, item)
196+
}
197+
}
198+
return result
199+
}
200+
184201
// WithoutEmpty returns slice excluding zero values.
185202
//
186203
// Deprecated: Use lo.Compact instead.

intersect_example_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package lo
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
func ExampleWithoutBy() {
8+
type User struct {
9+
ID int
10+
Name string
11+
}
12+
// original users
13+
users := []User{
14+
{ID: 1, Name: "Alice"},
15+
{ID: 2, Name: "Bob"},
16+
{ID: 3, Name: "Charlie"},
17+
}
18+
19+
// exclude users with IDs 2 and 3
20+
excludedIDs := []int{2, 3}
21+
22+
// extract function to get the user ID
23+
extractID := func(user User) int {
24+
return user.ID
25+
}
26+
27+
// filtering users
28+
filteredUsers := WithoutBy(users, extractID, excludedIDs...)
29+
30+
// output the filtered users
31+
fmt.Printf("%v\n", filteredUsers)
32+
// Output:
33+
// [{1 Alice}]
34+
}

intersect_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,26 @@ func TestWithout(t *testing.T) {
270270
is.IsType(nonempty, allStrings, "type preserved")
271271
}
272272

273+
func TestWithoutBy(t *testing.T) {
274+
t.Parallel()
275+
is := assert.New(t)
276+
277+
type User struct {
278+
Name string
279+
Age int
280+
}
281+
282+
result1 := WithoutBy([]User{{Name: "nick"}, {Name: "peter"}},
283+
func(item User) string {
284+
return item.Name
285+
}, "nick", "lily")
286+
result2 := WithoutBy([]User{}, func(item User) int { return item.Age }, 1, 2, 3)
287+
result3 := WithoutBy([]User{}, func(item User) string { return item.Name })
288+
is.Equal(result1, []User{{Name: "peter"}})
289+
is.Equal(result2, []User{})
290+
is.Equal(result3, []User{})
291+
}
292+
273293
func TestWithoutEmpty(t *testing.T) {
274294
t.Parallel()
275295
is := assert.New(t)

0 commit comments

Comments
 (0)