Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,8 @@ Example5:Convert to map
```go
ToMap([]int{1, 2, 3, 4, 5}, func(i int) (string, int) { return strconv.Itoa(i), i })
// {"1":1, "2":2, "3":3, "4":4, "5":5}
ToSet([]int{1, 2, 3, 3, 2})
// {1: true, 2: true, 3: true}
ToMapValues([]int{1, 2, 3, 4, 5}, strconv.Itoa)
// {"1":1, "2":2, "3":3, "4":4, "5":5}
GroupBy([]int{1, 2, 3, 4, 5}, func(i int) string {
Expand Down Expand Up @@ -596,7 +598,7 @@ import jsoniter "github.com/json-iterator/go"

gson.MarshalBy(jsoniter.ConfigDefault, testcase)
// []byte(`{"name":"test","age":10}`) nil
gson.MarshalString(jsoniter.ConfigDefault, testcase)
gson.MarshalString(jsoniter.ConfigDefault, testcase)
// {"name":"test","age":10}`, nil
gson.UnmarshalBy[testStruct](jsoniter.ConfigDefault, `{"name":"test","age":10}`)
// testStruct{Name: "test", Age: 10}, nil
Expand Down
4 changes: 3 additions & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,8 @@ gslice.Sum([]int{1, 2, 3, 4, 5})
```go
ToMap([]int{1, 2, 3, 4, 5}, func(i int) (string, int) { return strconv.Itoa(i), i })
// {"1":1, "2":2, "3":3, "4":4, "5":5}
ToSet([]int{1, 2, 3, 3, 2})
// {1: true, 2: true, 3: true}
ToMapValues([]int{1, 2, 3, 4, 5}, strconv.Itoa)
// {"1":1, "2":2, "3":3, "4":4, "5":5}
GroupBy([]int{1, 2, 3, 4, 5}, func(i int) string {
Expand Down Expand Up @@ -597,7 +599,7 @@ import jsoniter "github.com/json-iterator/go"

gson.MarshalBy(jsoniter.ConfigDefault, testcase)
// []byte(`{"name":"test","age":10}`) nil
gson.MarshalString(jsoniter.ConfigDefault, testcase)
gson.MarshalString(jsoniter.ConfigDefault, testcase)
// {"name":"test","age":10}`, nil
gson.UnmarshalBy[testStruct](jsoniter.ConfigDefault, `{"name":"test","age":10}`)
// testStruct{Name: "test", Age: 10}, nil
Expand Down
20 changes: 19 additions & 1 deletion gslice/gslice.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
//
// Convert to Map:
//
// - [ToMap], [ToMapValues]
// - [ToMap], [ToMapValues], [ToSet]
// - [GroupBy]
//
// Set operations:
Expand Down Expand Up @@ -1116,6 +1116,24 @@ func ToMapValues[T any, K comparable](s []T, f func(T) K) map[K]T {
return iter.ToMapValues(f, iter.StealSlice(s))
}

// ToSet collects elements of a slice into a set-like structure represented by map[T]bool.
// Each unique element from the input slice becomes a key in the map with the value `true`.
// Duplicate elements are automatically de-duplicated due to map key uniqueness.
//
// 🚀 EXAMPLE:
//
// s := []int{1, 2, 2, 3}
// ToSet(s) ⏩ map[int]bool{1: true, 2: true, 3: true}
//
// 🧠 NOTE:
Comment thread
GarrickZ2 marked this conversation as resolved.
Outdated
//
// The element type T must be comparable, as required by Go map keys.
//
// 💡 AKA: setOf(...) in Kotlin, .toSet() in Python
func ToSet[T comparable](s []T) map[T]bool {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have a collection/set data type, the name ToSet may be misleading. I prefer using ToBoolMap, as we already have ToMap function, and in the future we may add ToStructMap for returning map[V]strcut{}.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense — my initial thought was to mirror naming from languages like Kotlin/Python (toSet), but I can see how ToBoolMap better aligns with our existing ToMap and avoids potential confusion with collection/set. I've updated the name accordingly.

return ToMap(s, func(t T) (T, bool) { return t, true })
}

// PtrOf returns pointers that point to equivalent elements of slice s.
// ([]T → []*T).
//
Expand Down
2 changes: 2 additions & 0 deletions gslice/gslice_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func Example() {
// Convert to Map
fmt.Println(gson.ToString(ToMap([]int{1, 2, 3, 4, 5}, func(i int) (string, int) { return strconv.Itoa(i), i }))) // {"1":1,"2":2,"3":3,"4":4,"5":5}
fmt.Println(gson.ToString(ToMapValues([]int{1, 2, 3, 4, 5}, strconv.Itoa))) // {"1":1,"2":2,"3":3,"4":4,"5":5}
fmt.Println(gson.ToString(ToSet([]int{1, 2, 3, 3, 2}))) // {"1":true,"2":true,"3":true}
fmt.Println(gson.ToString(GroupBy([]int{1, 2, 3, 4, 5}, func(i int) string {
if i%2 == 0 {
return "even"
Expand Down Expand Up @@ -119,6 +120,7 @@ func Example() {
// 15
// {"1":1,"2":2,"3":3,"4":4,"5":5}
// {"1":1,"2":2,"3":3,"4":4,"5":5}
// {"1":true,"2":true,"3":true}
// {"even":[2,4],"odd":[1,3,5]}
// [1 2 3 4 5]
// [3]
Expand Down
8 changes: 8 additions & 0 deletions gslice/gslice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,14 @@ func TestToMap(t *testing.T) {
ToMap([]Foo{{1, "one"}, {2, "two"}, {3, "three"}}, mapper))
}

func TestToSet(t *testing.T) {
assert.Equal(t, map[int]bool{}, ToSet([]int{}))
assert.Equal(t, map[int]bool{1: true, 2: true, 3: true}, ToSet([]int{1, 2, 2, 3}))
assert.Equal(t,
map[string]bool{"a": true, "b": true},
ToSet([]string{"a", "b", "a", "a", "b"}))
}

func TestDivide(t *testing.T) {
{
s := []int{0, 1, 2, 3, 4}
Expand Down
Loading