Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best way to remove element from Set #53

Closed
Nhoya opened this issue Aug 27, 2017 · 3 comments
Closed

Best way to remove element from Set #53

Nhoya opened this issue Aug 27, 2017 · 3 comments

Comments

@Nhoya
Copy link

Nhoya commented Aug 27, 2017

Let's say i'v a Set, i want to cycle all the elements in this set and ask the user to select which element remove from the set, the problem now is that if you try to remove the element with myset.Remove(element) in the cycle it will hang (probably because you cant iterate the elements and remove them in the same time).

mySet := mapsetNewSet()
//fill set with stuff
myIt := mySet.Iterator()
scanner := bufio.NewScanner(os.Stdin)
for stuff := range myIt.C {
                        fmt.Println("Found " + stuff.(string) + " remove it?[Y/n]")
                        scanner.Scan()
                        text := scanner.Text()
                        if text == "y" || text == "Y" {
                                fmt.Println("removing")
                                mySet.Remove(stuff) //this will hang
                                fmt.Println("done")
                        }
}

One solution is to create another Set and filling it with the value from the cycle and after the end of cycle use myset.Difference(OtherSet) but i don't want to create another set just for this, do you have another solution more efficient than this

EDIT: as i can see, you can't add stuff to a set while you are iterating another set, still will hang

mySet := mapsetNewSet()
diffSet := mapsetNewSet()
//fill set with stuff
myIt := mySet.Iterator()
scanner := bufio.NewScanner(os.Stdin)
for stuff := range myIt.C {
                        fmt.Println("Found " + stuff.(string) + " remove it?[Y/n]")
                        scanner.Scan()
                        text := scanner.Text()
                        if text == "y" || text == "Y" {
                                fmt.Println("removing")
                                diffSet.Add(stuff) //this will hang too
                                fmt.Println("done")
                        }
}
mySet := mySet.Difference(diffSet)
@deckarep
Copy link
Owner

deckarep commented Aug 27, 2017

So, it's typically always a bad idea to iterate a data-structure and mutate it during iteration as in your first example. The reason is because it pretty much invalidates the iterator.

Your second example is actually the proper way to do it, especially when dealing with sets. You start off with your original set called: mySet which has some data. You create a different set that is empty. This represents the stuff "taken" out of the original set. But instead of actually taking anything out, you add what is to be removed into diffSet.

Then you just take the difference.

In fact the example works for me without hanging at all.

package main

import (
	"bufio"
	"fmt"
	"os"

	mapset "github.com/deckarep/golang-set"
)

func main() {
	mySet := mapset.NewSet()
	mySet.Add("a")
	mySet.Add("b")
	mySet.Add("c")

	diffSet := mapset.NewSet()
	//fill set with stuff
	myIt := mySet.Iterator()
	scanner := bufio.NewScanner(os.Stdin)
	for stuff := range myIt.C {
		fmt.Println("Found " + stuff.(string) + " remove it?[Y/n]")
		scanner.Scan()
		text := scanner.Text()
		if text == "y" || text == "Y" {
			fmt.Println("removing")
			diffSet.Add(stuff) //this will hang too
			fmt.Println("done")
		}
	}
	mySet = mySet.Difference(diffSet)
	fmt.Printf("result: %+v\n", mySet)
}

@deckarep
Copy link
Owner

Here is the output of the run above:

Found a remove it?[Y/n]
y
removing
done
Found b remove it?[Y/n]
n
Found c remove it?[Y/n]
n
result: Set{b, c}

@Nhoya
Copy link
Author

Nhoya commented Aug 27, 2017

Yea seems it's working, no idea why it hanged... well if that's the only way i will use it, thanks

@Nhoya Nhoya closed this as completed Aug 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants