Skip to content

Commit

Permalink
feat: add UniqMap (#527)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklaus-dev authored Jan 24, 2025
1 parent 9c6999e commit c32746c
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 0 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Supported helpers for slices:

- [Filter](#filter)
- [Map](#map)
- [UniqMap](#uniqmap)
- [FilterMap](#filtermap)
- [FlatMap](#flatmap)
- [Reduce](#reduce)
Expand Down Expand Up @@ -345,6 +346,23 @@ lop.Map([]int64{1, 2, 3, 4}, func(x int64, _ int) string {
// []string{"1", "2", "3", "4"}
```

### UniqMap

UniqMap manipulates a slice and transforms it to a slice of another type with unique values.

```go
type User struct {
Name string
Age int
}
users := []User{{Name: "Alex", Age: 10}, {Name: "Alex", Age: 12}, {Name: "Bob", Age: 11}, {Name: "Alice", Age: 20}}

names := UniqMap(users, func(u User, index int) string {
return u.Name
})
// []string{"Alex", "Bob", "Alice"}
```

### FilterMap

Returns a slice which obtained after both filtering and mapping using the given callback function.
Expand Down
15 changes: 15 additions & 0 deletions slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@ func Map[T any, R any](collection []T, iteratee func(item T, index int) R) []R {
return result
}

// UniqMap manipulates a slice and transforms it to a slice of another type with unique values.
func UniqMap[T any, R comparable](collection []T, iteratee func(item T, index int) R) []R {
result := make([]R, 0, len(collection))
seen := make(map[R]struct{}, len(collection))

for i, item := range collection {
r := iteratee(item, i)
if _, ok := seen[r]; !ok {
result = append(result, r)
seen[r] = struct{}{}
}
}
return result
}

// FilterMap returns a slice which obtained after both filtering and mapping using the given callback function.
// The callback function should return two values:
// - the result of the mapping operation and
Expand Down
15 changes: 15 additions & 0 deletions slice_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@ func ExampleMap() {
// Output: [2 4 6 8]
}

func ExampleUniqMap() {
type User struct {
Name string
Age int
}
users := []User{{Name: "Alex", Age: 10}, {Name: "Alex", Age: 12}, {Name: "Bob", Age: 11}, {Name: "Alice", Age: 20}}

result := UniqMap(users, func(u User, index int) string {
return u.Name
})

fmt.Printf("%v", result)
// Output: [Alex Bob Alice]
}

func ExampleFilterMap() {
list := []int64{1, 2, 3, 4}

Expand Down
17 changes: 17 additions & 0 deletions slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,23 @@ func TestMap(t *testing.T) {
is.Equal(result2, []string{"1", "2", "3", "4"})
}

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

type User struct {
Name string
age int
}

users := []User{{Name: "Alice", age: 20}, {Name: "Alex", age: 21}, {Name: "Alex", age: 22}}
result := UniqMap(users, func(item User, index int) string {
return item.Name
})

is.Equal(result, []string{"Alice", "Alex"})
}

func TestFilterMap(t *testing.T) {
t.Parallel()
is := assert.New(t)
Expand Down

0 comments on commit c32746c

Please sign in to comment.