I wonder how to implement set struct as map value [closed]
I want to use set as map value on golang. So I coded like this:
import (
"fmt"
"reflect"
)
type TestSet struct {
Items Test
}
func (ts *TestSet) Add(t *Test) {
ok := true
for _, item := range ts.Items {
if item.Equal(t) {
ok = false
break
}
}
if ok {
ts.Items = append(ts.Items, *t)
}
}
type Test struct {
phoneNumber string
name string
friends string // i add this field! (**edit**)
}
func (t *Test) Equal(t2 *Test) bool {
if t.phoneNumber != t2.phoneNumber || t.name != t2.name {
return false
}
if !reflect.DeepEqual(t.friends, t2.friends) {
return false
}
return true
}
And I want to use structure like below code:
val := make(map[int]*TestSet)
val[1] = &TestSet{}
val[1].Add(&Test{phoneNumber: "8210", name: "minji", friends: string{"myself"})
However my TestSet
always has to iterate over the entire item to exist its value. So Add()
time complexity O(n).
I want to reduce that time complexity to O(1). (like python set in
)
But, I do not know what to do. Should I use another map?
Any good ideas?
go
closed as too broad by Volker, Owen Pauling, Umair, Sahil Mahajan Mj, GhostCat Nov 16 '18 at 12:16
Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.
|
show 2 more comments
I want to use set as map value on golang. So I coded like this:
import (
"fmt"
"reflect"
)
type TestSet struct {
Items Test
}
func (ts *TestSet) Add(t *Test) {
ok := true
for _, item := range ts.Items {
if item.Equal(t) {
ok = false
break
}
}
if ok {
ts.Items = append(ts.Items, *t)
}
}
type Test struct {
phoneNumber string
name string
friends string // i add this field! (**edit**)
}
func (t *Test) Equal(t2 *Test) bool {
if t.phoneNumber != t2.phoneNumber || t.name != t2.name {
return false
}
if !reflect.DeepEqual(t.friends, t2.friends) {
return false
}
return true
}
And I want to use structure like below code:
val := make(map[int]*TestSet)
val[1] = &TestSet{}
val[1].Add(&Test{phoneNumber: "8210", name: "minji", friends: string{"myself"})
However my TestSet
always has to iterate over the entire item to exist its value. So Add()
time complexity O(n).
I want to reduce that time complexity to O(1). (like python set in
)
But, I do not know what to do. Should I use another map?
Any good ideas?
go
closed as too broad by Volker, Owen Pauling, Umair, Sahil Mahajan Mj, GhostCat Nov 16 '18 at 12:16
Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.
What do you mean byval[1]
?
– Shudipta Sharma
Nov 16 '18 at 4:14
@ShudiptaSharma oops, I edit the samples!
– minji
Nov 16 '18 at 4:20
But what you wrote on the question is not llike set rather than a map. Do you want to convert your map into a set implementation?
– Shudipta Sharma
Nov 16 '18 at 4:33
@ShudiptaSharma my english is not good, sorry ;( as a result, what i want is like this sample python codea.setdefault(1, set()).add(Test())
a is dictionary. and a.values has always unique structure(i used custom class in python and override__hash__
method). if map can do this, please help...
– minji
Nov 16 '18 at 4:44
Do you want like thisval := make(map[int]*Test)
so that you can store theTest
structs by order they are inserted?
– Shudipta Sharma
Nov 16 '18 at 4:52
|
show 2 more comments
I want to use set as map value on golang. So I coded like this:
import (
"fmt"
"reflect"
)
type TestSet struct {
Items Test
}
func (ts *TestSet) Add(t *Test) {
ok := true
for _, item := range ts.Items {
if item.Equal(t) {
ok = false
break
}
}
if ok {
ts.Items = append(ts.Items, *t)
}
}
type Test struct {
phoneNumber string
name string
friends string // i add this field! (**edit**)
}
func (t *Test) Equal(t2 *Test) bool {
if t.phoneNumber != t2.phoneNumber || t.name != t2.name {
return false
}
if !reflect.DeepEqual(t.friends, t2.friends) {
return false
}
return true
}
And I want to use structure like below code:
val := make(map[int]*TestSet)
val[1] = &TestSet{}
val[1].Add(&Test{phoneNumber: "8210", name: "minji", friends: string{"myself"})
However my TestSet
always has to iterate over the entire item to exist its value. So Add()
time complexity O(n).
I want to reduce that time complexity to O(1). (like python set in
)
But, I do not know what to do. Should I use another map?
Any good ideas?
go
I want to use set as map value on golang. So I coded like this:
import (
"fmt"
"reflect"
)
type TestSet struct {
Items Test
}
func (ts *TestSet) Add(t *Test) {
ok := true
for _, item := range ts.Items {
if item.Equal(t) {
ok = false
break
}
}
if ok {
ts.Items = append(ts.Items, *t)
}
}
type Test struct {
phoneNumber string
name string
friends string // i add this field! (**edit**)
}
func (t *Test) Equal(t2 *Test) bool {
if t.phoneNumber != t2.phoneNumber || t.name != t2.name {
return false
}
if !reflect.DeepEqual(t.friends, t2.friends) {
return false
}
return true
}
And I want to use structure like below code:
val := make(map[int]*TestSet)
val[1] = &TestSet{}
val[1].Add(&Test{phoneNumber: "8210", name: "minji", friends: string{"myself"})
However my TestSet
always has to iterate over the entire item to exist its value. So Add()
time complexity O(n).
I want to reduce that time complexity to O(1). (like python set in
)
But, I do not know what to do. Should I use another map?
Any good ideas?
go
go
edited Nov 16 '18 at 5:46
minji
asked Nov 16 '18 at 3:19
minjiminji
15718
15718
closed as too broad by Volker, Owen Pauling, Umair, Sahil Mahajan Mj, GhostCat Nov 16 '18 at 12:16
Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.
closed as too broad by Volker, Owen Pauling, Umair, Sahil Mahajan Mj, GhostCat Nov 16 '18 at 12:16
Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.
What do you mean byval[1]
?
– Shudipta Sharma
Nov 16 '18 at 4:14
@ShudiptaSharma oops, I edit the samples!
– minji
Nov 16 '18 at 4:20
But what you wrote on the question is not llike set rather than a map. Do you want to convert your map into a set implementation?
– Shudipta Sharma
Nov 16 '18 at 4:33
@ShudiptaSharma my english is not good, sorry ;( as a result, what i want is like this sample python codea.setdefault(1, set()).add(Test())
a is dictionary. and a.values has always unique structure(i used custom class in python and override__hash__
method). if map can do this, please help...
– minji
Nov 16 '18 at 4:44
Do you want like thisval := make(map[int]*Test)
so that you can store theTest
structs by order they are inserted?
– Shudipta Sharma
Nov 16 '18 at 4:52
|
show 2 more comments
What do you mean byval[1]
?
– Shudipta Sharma
Nov 16 '18 at 4:14
@ShudiptaSharma oops, I edit the samples!
– minji
Nov 16 '18 at 4:20
But what you wrote on the question is not llike set rather than a map. Do you want to convert your map into a set implementation?
– Shudipta Sharma
Nov 16 '18 at 4:33
@ShudiptaSharma my english is not good, sorry ;( as a result, what i want is like this sample python codea.setdefault(1, set()).add(Test())
a is dictionary. and a.values has always unique structure(i used custom class in python and override__hash__
method). if map can do this, please help...
– minji
Nov 16 '18 at 4:44
Do you want like thisval := make(map[int]*Test)
so that you can store theTest
structs by order they are inserted?
– Shudipta Sharma
Nov 16 '18 at 4:52
What do you mean by
val[1]
?– Shudipta Sharma
Nov 16 '18 at 4:14
What do you mean by
val[1]
?– Shudipta Sharma
Nov 16 '18 at 4:14
@ShudiptaSharma oops, I edit the samples!
– minji
Nov 16 '18 at 4:20
@ShudiptaSharma oops, I edit the samples!
– minji
Nov 16 '18 at 4:20
But what you wrote on the question is not llike set rather than a map. Do you want to convert your map into a set implementation?
– Shudipta Sharma
Nov 16 '18 at 4:33
But what you wrote on the question is not llike set rather than a map. Do you want to convert your map into a set implementation?
– Shudipta Sharma
Nov 16 '18 at 4:33
@ShudiptaSharma my english is not good, sorry ;( as a result, what i want is like this sample python code
a.setdefault(1, set()).add(Test())
a is dictionary. and a.values has always unique structure(i used custom class in python and override __hash__
method). if map can do this, please help...– minji
Nov 16 '18 at 4:44
@ShudiptaSharma my english is not good, sorry ;( as a result, what i want is like this sample python code
a.setdefault(1, set()).add(Test())
a is dictionary. and a.values has always unique structure(i used custom class in python and override __hash__
method). if map can do this, please help...– minji
Nov 16 '18 at 4:44
Do you want like this
val := make(map[int]*Test)
so that you can store the Test
structs by order they are inserted?– Shudipta Sharma
Nov 16 '18 at 4:52
Do you want like this
val := make(map[int]*Test)
so that you can store the Test
structs by order they are inserted?– Shudipta Sharma
Nov 16 '18 at 4:52
|
show 2 more comments
3 Answers
3
active
oldest
votes
Sets are often implemented as maps with no value. A struct{}
is effectively empty in Go.
type Empty struct {}
type TestSet struct {
set map[Test]Empty
}
In order for this to work, Test
must be comparable.
Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
So Test
is comparable.
package main;
import (
"fmt"
)
type Empty struct {}
type TestSet struct {
set map[Test]Empty
}
func (ts *TestSet) Add(t Test) bool {
if _, present := ts.set[t]; present {
return false
} else {
ts.set[t] = Empty{}
return true
}
}
type Test struct {
phoneNumber string
name string
}
func main() {
set := TestSet{ set: make(map[Test]Empty) }
test1 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }
test2 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }
test3 := Test{ phoneNumber: "123-555-5555", name: "Yarrow Hock" }
if set.Add( test1 ) {
fmt.Println("Added 1")
}
if set.Add( test2 ) {
fmt.Println("Added 2")
}
if set.Add( test3 ) {
fmt.Println("Added 3")
}
for test := range set.set {
fmt.Println(test.phoneNumber)
}
}
You can also use the golang-set library.
1
A map with no value usesstruct{}
as the value type for the map.
– ratorx
Nov 16 '18 at 4:22
@ratorx How do you set that?ts.set[t] = ?
– Schwern
Nov 16 '18 at 4:34
1
type Empty struct{} type TestSet struct { set map[Test]Empty } ... ts.set[t] = Empty
– Shudipta Sharma
Nov 16 '18 at 4:35
@ShudiptaSharma Got it.ts.set[t] = struct{}{}
– Schwern
Nov 16 '18 at 4:38
You got that right.
– Shudipta Sharma
Nov 16 '18 at 4:41
|
show 2 more comments
You can use a map to emulate a set in golang by making the value type struct{}
. Some example code for your Test
struct:
package main
import "fmt"
type TestSet map[Test]struct{}
func (ts TestSet) Add(t Test) {
ts[t] = struct{}{}
}
type Test struct {
phoneNumber string
name string
}
func main() {
ts := TestSet{}
t1 := Test{"a", "b"}
t2 := Test{"a", "b"}
ts.Add(t1)
ts.Add(t2)
fmt.Println(ts) // Output: map[{a b}:{}]
}
This doesn't match your function signatures exactly, as I use values rather than references. This means that I don't have to define a custom Equals
functions as you have done. Also, by passing in the argument as a value, the map checks the structs themselves for equality rather than the references.
A thing to note is that this method will only work if the structs are comparable. More info is in this StackOverflow answer which quotes the spec.
add a comment |
Perhaps, something like this:
package main
type Test struct {
phoneNumber string
name string
}
type TestSet struct {
Items map[string]bool
}
func (ts *TestSet) Add(t *Test) {
ts.Items[t.phoneNumber+"x80"+t.name] = true
}
func main() {}
Playground: https://play.golang.org/p/48fVQcvp3sW
how about If the values ofphoneNumber
andname
are changed and add again?
– minji
Nov 16 '18 at 4:34
@minji: Then there will be twoItems
.
– peterSO
Nov 16 '18 at 4:55
@peterOS sorry, my question is stupid. ignore it. I wonder how about this?ts.Add(&Test{"10", "5"})
andts.Add(&Test{"1", "05"})
it has only 1 items.
– minji
Nov 16 '18 at 4:58
@minji: See my revised answer.
– peterSO
Nov 16 '18 at 8:20
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sets are often implemented as maps with no value. A struct{}
is effectively empty in Go.
type Empty struct {}
type TestSet struct {
set map[Test]Empty
}
In order for this to work, Test
must be comparable.
Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
So Test
is comparable.
package main;
import (
"fmt"
)
type Empty struct {}
type TestSet struct {
set map[Test]Empty
}
func (ts *TestSet) Add(t Test) bool {
if _, present := ts.set[t]; present {
return false
} else {
ts.set[t] = Empty{}
return true
}
}
type Test struct {
phoneNumber string
name string
}
func main() {
set := TestSet{ set: make(map[Test]Empty) }
test1 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }
test2 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }
test3 := Test{ phoneNumber: "123-555-5555", name: "Yarrow Hock" }
if set.Add( test1 ) {
fmt.Println("Added 1")
}
if set.Add( test2 ) {
fmt.Println("Added 2")
}
if set.Add( test3 ) {
fmt.Println("Added 3")
}
for test := range set.set {
fmt.Println(test.phoneNumber)
}
}
You can also use the golang-set library.
1
A map with no value usesstruct{}
as the value type for the map.
– ratorx
Nov 16 '18 at 4:22
@ratorx How do you set that?ts.set[t] = ?
– Schwern
Nov 16 '18 at 4:34
1
type Empty struct{} type TestSet struct { set map[Test]Empty } ... ts.set[t] = Empty
– Shudipta Sharma
Nov 16 '18 at 4:35
@ShudiptaSharma Got it.ts.set[t] = struct{}{}
– Schwern
Nov 16 '18 at 4:38
You got that right.
– Shudipta Sharma
Nov 16 '18 at 4:41
|
show 2 more comments
Sets are often implemented as maps with no value. A struct{}
is effectively empty in Go.
type Empty struct {}
type TestSet struct {
set map[Test]Empty
}
In order for this to work, Test
must be comparable.
Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
So Test
is comparable.
package main;
import (
"fmt"
)
type Empty struct {}
type TestSet struct {
set map[Test]Empty
}
func (ts *TestSet) Add(t Test) bool {
if _, present := ts.set[t]; present {
return false
} else {
ts.set[t] = Empty{}
return true
}
}
type Test struct {
phoneNumber string
name string
}
func main() {
set := TestSet{ set: make(map[Test]Empty) }
test1 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }
test2 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }
test3 := Test{ phoneNumber: "123-555-5555", name: "Yarrow Hock" }
if set.Add( test1 ) {
fmt.Println("Added 1")
}
if set.Add( test2 ) {
fmt.Println("Added 2")
}
if set.Add( test3 ) {
fmt.Println("Added 3")
}
for test := range set.set {
fmt.Println(test.phoneNumber)
}
}
You can also use the golang-set library.
1
A map with no value usesstruct{}
as the value type for the map.
– ratorx
Nov 16 '18 at 4:22
@ratorx How do you set that?ts.set[t] = ?
– Schwern
Nov 16 '18 at 4:34
1
type Empty struct{} type TestSet struct { set map[Test]Empty } ... ts.set[t] = Empty
– Shudipta Sharma
Nov 16 '18 at 4:35
@ShudiptaSharma Got it.ts.set[t] = struct{}{}
– Schwern
Nov 16 '18 at 4:38
You got that right.
– Shudipta Sharma
Nov 16 '18 at 4:41
|
show 2 more comments
Sets are often implemented as maps with no value. A struct{}
is effectively empty in Go.
type Empty struct {}
type TestSet struct {
set map[Test]Empty
}
In order for this to work, Test
must be comparable.
Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
So Test
is comparable.
package main;
import (
"fmt"
)
type Empty struct {}
type TestSet struct {
set map[Test]Empty
}
func (ts *TestSet) Add(t Test) bool {
if _, present := ts.set[t]; present {
return false
} else {
ts.set[t] = Empty{}
return true
}
}
type Test struct {
phoneNumber string
name string
}
func main() {
set := TestSet{ set: make(map[Test]Empty) }
test1 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }
test2 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }
test3 := Test{ phoneNumber: "123-555-5555", name: "Yarrow Hock" }
if set.Add( test1 ) {
fmt.Println("Added 1")
}
if set.Add( test2 ) {
fmt.Println("Added 2")
}
if set.Add( test3 ) {
fmt.Println("Added 3")
}
for test := range set.set {
fmt.Println(test.phoneNumber)
}
}
You can also use the golang-set library.
Sets are often implemented as maps with no value. A struct{}
is effectively empty in Go.
type Empty struct {}
type TestSet struct {
set map[Test]Empty
}
In order for this to work, Test
must be comparable.
Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
So Test
is comparable.
package main;
import (
"fmt"
)
type Empty struct {}
type TestSet struct {
set map[Test]Empty
}
func (ts *TestSet) Add(t Test) bool {
if _, present := ts.set[t]; present {
return false
} else {
ts.set[t] = Empty{}
return true
}
}
type Test struct {
phoneNumber string
name string
}
func main() {
set := TestSet{ set: make(map[Test]Empty) }
test1 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }
test2 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }
test3 := Test{ phoneNumber: "123-555-5555", name: "Yarrow Hock" }
if set.Add( test1 ) {
fmt.Println("Added 1")
}
if set.Add( test2 ) {
fmt.Println("Added 2")
}
if set.Add( test3 ) {
fmt.Println("Added 3")
}
for test := range set.set {
fmt.Println(test.phoneNumber)
}
}
You can also use the golang-set library.
edited Nov 16 '18 at 4:39
answered Nov 16 '18 at 4:20
SchwernSchwern
89.1k17102232
89.1k17102232
1
A map with no value usesstruct{}
as the value type for the map.
– ratorx
Nov 16 '18 at 4:22
@ratorx How do you set that?ts.set[t] = ?
– Schwern
Nov 16 '18 at 4:34
1
type Empty struct{} type TestSet struct { set map[Test]Empty } ... ts.set[t] = Empty
– Shudipta Sharma
Nov 16 '18 at 4:35
@ShudiptaSharma Got it.ts.set[t] = struct{}{}
– Schwern
Nov 16 '18 at 4:38
You got that right.
– Shudipta Sharma
Nov 16 '18 at 4:41
|
show 2 more comments
1
A map with no value usesstruct{}
as the value type for the map.
– ratorx
Nov 16 '18 at 4:22
@ratorx How do you set that?ts.set[t] = ?
– Schwern
Nov 16 '18 at 4:34
1
type Empty struct{} type TestSet struct { set map[Test]Empty } ... ts.set[t] = Empty
– Shudipta Sharma
Nov 16 '18 at 4:35
@ShudiptaSharma Got it.ts.set[t] = struct{}{}
– Schwern
Nov 16 '18 at 4:38
You got that right.
– Shudipta Sharma
Nov 16 '18 at 4:41
1
1
A map with no value uses
struct{}
as the value type for the map.– ratorx
Nov 16 '18 at 4:22
A map with no value uses
struct{}
as the value type for the map.– ratorx
Nov 16 '18 at 4:22
@ratorx How do you set that?
ts.set[t] = ?
– Schwern
Nov 16 '18 at 4:34
@ratorx How do you set that?
ts.set[t] = ?
– Schwern
Nov 16 '18 at 4:34
1
1
type Empty struct{} type TestSet struct { set map[Test]Empty } ... ts.set[t] = Empty
– Shudipta Sharma
Nov 16 '18 at 4:35
type Empty struct{} type TestSet struct { set map[Test]Empty } ... ts.set[t] = Empty
– Shudipta Sharma
Nov 16 '18 at 4:35
@ShudiptaSharma Got it.
ts.set[t] = struct{}{}
– Schwern
Nov 16 '18 at 4:38
@ShudiptaSharma Got it.
ts.set[t] = struct{}{}
– Schwern
Nov 16 '18 at 4:38
You got that right.
– Shudipta Sharma
Nov 16 '18 at 4:41
You got that right.
– Shudipta Sharma
Nov 16 '18 at 4:41
|
show 2 more comments
You can use a map to emulate a set in golang by making the value type struct{}
. Some example code for your Test
struct:
package main
import "fmt"
type TestSet map[Test]struct{}
func (ts TestSet) Add(t Test) {
ts[t] = struct{}{}
}
type Test struct {
phoneNumber string
name string
}
func main() {
ts := TestSet{}
t1 := Test{"a", "b"}
t2 := Test{"a", "b"}
ts.Add(t1)
ts.Add(t2)
fmt.Println(ts) // Output: map[{a b}:{}]
}
This doesn't match your function signatures exactly, as I use values rather than references. This means that I don't have to define a custom Equals
functions as you have done. Also, by passing in the argument as a value, the map checks the structs themselves for equality rather than the references.
A thing to note is that this method will only work if the structs are comparable. More info is in this StackOverflow answer which quotes the spec.
add a comment |
You can use a map to emulate a set in golang by making the value type struct{}
. Some example code for your Test
struct:
package main
import "fmt"
type TestSet map[Test]struct{}
func (ts TestSet) Add(t Test) {
ts[t] = struct{}{}
}
type Test struct {
phoneNumber string
name string
}
func main() {
ts := TestSet{}
t1 := Test{"a", "b"}
t2 := Test{"a", "b"}
ts.Add(t1)
ts.Add(t2)
fmt.Println(ts) // Output: map[{a b}:{}]
}
This doesn't match your function signatures exactly, as I use values rather than references. This means that I don't have to define a custom Equals
functions as you have done. Also, by passing in the argument as a value, the map checks the structs themselves for equality rather than the references.
A thing to note is that this method will only work if the structs are comparable. More info is in this StackOverflow answer which quotes the spec.
add a comment |
You can use a map to emulate a set in golang by making the value type struct{}
. Some example code for your Test
struct:
package main
import "fmt"
type TestSet map[Test]struct{}
func (ts TestSet) Add(t Test) {
ts[t] = struct{}{}
}
type Test struct {
phoneNumber string
name string
}
func main() {
ts := TestSet{}
t1 := Test{"a", "b"}
t2 := Test{"a", "b"}
ts.Add(t1)
ts.Add(t2)
fmt.Println(ts) // Output: map[{a b}:{}]
}
This doesn't match your function signatures exactly, as I use values rather than references. This means that I don't have to define a custom Equals
functions as you have done. Also, by passing in the argument as a value, the map checks the structs themselves for equality rather than the references.
A thing to note is that this method will only work if the structs are comparable. More info is in this StackOverflow answer which quotes the spec.
You can use a map to emulate a set in golang by making the value type struct{}
. Some example code for your Test
struct:
package main
import "fmt"
type TestSet map[Test]struct{}
func (ts TestSet) Add(t Test) {
ts[t] = struct{}{}
}
type Test struct {
phoneNumber string
name string
}
func main() {
ts := TestSet{}
t1 := Test{"a", "b"}
t2 := Test{"a", "b"}
ts.Add(t1)
ts.Add(t2)
fmt.Println(ts) // Output: map[{a b}:{}]
}
This doesn't match your function signatures exactly, as I use values rather than references. This means that I don't have to define a custom Equals
functions as you have done. Also, by passing in the argument as a value, the map checks the structs themselves for equality rather than the references.
A thing to note is that this method will only work if the structs are comparable. More info is in this StackOverflow answer which quotes the spec.
edited Nov 16 '18 at 4:04
answered Nov 16 '18 at 3:51
ratorxratorx
1376
1376
add a comment |
add a comment |
Perhaps, something like this:
package main
type Test struct {
phoneNumber string
name string
}
type TestSet struct {
Items map[string]bool
}
func (ts *TestSet) Add(t *Test) {
ts.Items[t.phoneNumber+"x80"+t.name] = true
}
func main() {}
Playground: https://play.golang.org/p/48fVQcvp3sW
how about If the values ofphoneNumber
andname
are changed and add again?
– minji
Nov 16 '18 at 4:34
@minji: Then there will be twoItems
.
– peterSO
Nov 16 '18 at 4:55
@peterOS sorry, my question is stupid. ignore it. I wonder how about this?ts.Add(&Test{"10", "5"})
andts.Add(&Test{"1", "05"})
it has only 1 items.
– minji
Nov 16 '18 at 4:58
@minji: See my revised answer.
– peterSO
Nov 16 '18 at 8:20
add a comment |
Perhaps, something like this:
package main
type Test struct {
phoneNumber string
name string
}
type TestSet struct {
Items map[string]bool
}
func (ts *TestSet) Add(t *Test) {
ts.Items[t.phoneNumber+"x80"+t.name] = true
}
func main() {}
Playground: https://play.golang.org/p/48fVQcvp3sW
how about If the values ofphoneNumber
andname
are changed and add again?
– minji
Nov 16 '18 at 4:34
@minji: Then there will be twoItems
.
– peterSO
Nov 16 '18 at 4:55
@peterOS sorry, my question is stupid. ignore it. I wonder how about this?ts.Add(&Test{"10", "5"})
andts.Add(&Test{"1", "05"})
it has only 1 items.
– minji
Nov 16 '18 at 4:58
@minji: See my revised answer.
– peterSO
Nov 16 '18 at 8:20
add a comment |
Perhaps, something like this:
package main
type Test struct {
phoneNumber string
name string
}
type TestSet struct {
Items map[string]bool
}
func (ts *TestSet) Add(t *Test) {
ts.Items[t.phoneNumber+"x80"+t.name] = true
}
func main() {}
Playground: https://play.golang.org/p/48fVQcvp3sW
Perhaps, something like this:
package main
type Test struct {
phoneNumber string
name string
}
type TestSet struct {
Items map[string]bool
}
func (ts *TestSet) Add(t *Test) {
ts.Items[t.phoneNumber+"x80"+t.name] = true
}
func main() {}
Playground: https://play.golang.org/p/48fVQcvp3sW
edited Nov 16 '18 at 8:19
answered Nov 16 '18 at 3:42
peterSOpeterSO
93.8k14160174
93.8k14160174
how about If the values ofphoneNumber
andname
are changed and add again?
– minji
Nov 16 '18 at 4:34
@minji: Then there will be twoItems
.
– peterSO
Nov 16 '18 at 4:55
@peterOS sorry, my question is stupid. ignore it. I wonder how about this?ts.Add(&Test{"10", "5"})
andts.Add(&Test{"1", "05"})
it has only 1 items.
– minji
Nov 16 '18 at 4:58
@minji: See my revised answer.
– peterSO
Nov 16 '18 at 8:20
add a comment |
how about If the values ofphoneNumber
andname
are changed and add again?
– minji
Nov 16 '18 at 4:34
@minji: Then there will be twoItems
.
– peterSO
Nov 16 '18 at 4:55
@peterOS sorry, my question is stupid. ignore it. I wonder how about this?ts.Add(&Test{"10", "5"})
andts.Add(&Test{"1", "05"})
it has only 1 items.
– minji
Nov 16 '18 at 4:58
@minji: See my revised answer.
– peterSO
Nov 16 '18 at 8:20
how about If the values of
phoneNumber
and name
are changed and add again?– minji
Nov 16 '18 at 4:34
how about If the values of
phoneNumber
and name
are changed and add again?– minji
Nov 16 '18 at 4:34
@minji: Then there will be two
Items
.– peterSO
Nov 16 '18 at 4:55
@minji: Then there will be two
Items
.– peterSO
Nov 16 '18 at 4:55
@peterOS sorry, my question is stupid. ignore it. I wonder how about this?
ts.Add(&Test{"10", "5"})
and ts.Add(&Test{"1", "05"})
it has only 1 items.– minji
Nov 16 '18 at 4:58
@peterOS sorry, my question is stupid. ignore it. I wonder how about this?
ts.Add(&Test{"10", "5"})
and ts.Add(&Test{"1", "05"})
it has only 1 items.– minji
Nov 16 '18 at 4:58
@minji: See my revised answer.
– peterSO
Nov 16 '18 at 8:20
@minji: See my revised answer.
– peterSO
Nov 16 '18 at 8:20
add a comment |
What do you mean by
val[1]
?– Shudipta Sharma
Nov 16 '18 at 4:14
@ShudiptaSharma oops, I edit the samples!
– minji
Nov 16 '18 at 4:20
But what you wrote on the question is not llike set rather than a map. Do you want to convert your map into a set implementation?
– Shudipta Sharma
Nov 16 '18 at 4:33
@ShudiptaSharma my english is not good, sorry ;( as a result, what i want is like this sample python code
a.setdefault(1, set()).add(Test())
a is dictionary. and a.values has always unique structure(i used custom class in python and override__hash__
method). if map can do this, please help...– minji
Nov 16 '18 at 4:44
Do you want like this
val := make(map[int]*Test)
so that you can store theTest
structs by order they are inserted?– Shudipta Sharma
Nov 16 '18 at 4:52