Remove Elements from a Hashset While Iterating

Remove Elements from a HashSet while Iterating

You can manually iterate over the elements of the set:

Iterator<Integer> iterator = set.iterator();
while (iterator.hasNext()) {
Integer element = iterator.next();
if (element % 2 == 0) {
iterator.remove();
}
}

You will often see this pattern using a for loop rather than a while loop:

for (Iterator<Integer> i = set.iterator(); i.hasNext();) {
Integer element = i.next();
if (element % 2 == 0) {
i.remove();
}
}

As people have pointed out, using a for loop is preferred because it keeps the iterator variable (i in this case) confined to a smaller scope.

Remove elements from HashSet on iteration

Keep a running set of numbers you have found.

This will allow you to have a one-pass solution.

Start with an empty running set, and iterate through your set of numbers. For each element you iterate through, if its sum-compliment is in the set, remove it from the iterator. Otherwise, add it to the running set.

HashSet<Integer> hs = new HashSet(arr);
HashSet<Integer> running = new HashSet();
int sum = 6;
Iterator<Integer> iter = hs.iterator();
while (iter.hasNext()) {
int num = iter.next();
if (running.contains(sum - num)) {
iter.remove();
} else {
running.add(num);
}
}

This code will modify the original HashSet, and both HashSets will contain the same contents at the end of the code block. In this case, it might be better just to use the running set at the end of the code and not modify the original. That will make this code far more flexible and reusable.

Remove elements from hashset inside hashmap while iterating through java stream

you can use forEach:

placementByConcept.entrySet().forEach(e -> e.getValue().removeIf(s -> s.getBeatObjectiveId().equals("non-scored")));

HashSet Iterating While Removing Items in C#

Use the RemoveWhere method of HashSet instead:

hashset.RemoveWhere(s => s == "somestring");

You specify a condition/predicate as the parameter to the method. Any item in the hashset that matches the predicate will be removed.

This avoids the problem of modifying the hashset whilst it is being iterated over.


In response to your comment:

's' represents the current item being evaluated from within the hashset.

The above code is equivalent to:

hashset.RemoveWhere(delegate(string s) {return s == "somestring";});

or:

hashset.RemoveWhere(ShouldRemove);

public bool ShouldRemove(string s)
{
return s == "somestring";
}

EDIT:
Something has just occurred to me: since HashSet is a set that contains no duplicate values, just calling hashset.Remove("somestring") will suffice. There is no need to do it in a loop as there will never be more than a single match.

Iterating over a HashSet and removing multiple elements in each iteration

The Iterator allows you to remove only the current element. For your case, you need not remove anything. I believe the reason you would like to remove is to avoid calling circularPrimes for a number that is a circular prime of a previously encountered number. In that case, you can simply check if the number is already part of the circularPrimes set - if yes don't call getAllRotations

while(it.hasNext()) {
Integer currentNum = it.next();
if (!circularPrimes.contains(currentNum)) {
Set<Integer> perms = getAllRotations(currentNum);

if(primes.containsAll(perms)) {
circularPrimes.addAll(perms);
}
}

}

Remove from hashset while iterating

Forgive me if I don't understand what you are trying to do.

Hash sets don't allow duplicates because the index of an item is the hash of the item. Two equal strings would have the same hash, and therefore the same index. Therefore if you simply combine any two hash sets, the result is free from duplicates.

Consider the following:

        var set1 = new HashSet<string>();
set1.Add("foo");
set1.Add("foo");

var set2 = new HashSet<string>();
set2.Add("foo");

var set3 = set1.Union(set2);

foreach (var val in set3)
{
Console.WriteLine(val);
}

The output of this code would be:

foo

Now if you are trying to ensure that hashset A doesn't include any items in hashset B, you could do something like this:

        var set1 = new HashSet<string>();
set1.Add("foo");
set1.Add("bar");

var set2 = new HashSet<string>();
set2.Add("foo");
set2.Add("baz");

foreach (var val in set2)
{
set1.Remove(val);
}

foreach (var val in set1)
{
Console.WriteLine(val);
}

The output of which would be:

bar

Giving this some more thought, you can subtract one set from another using the .Except method.

var set3 = set1.Except(set2);

This produces all the items in set1 that are not in set2

How should I iterate through a HashSet, removing certain elements, and altering others?

You cannot add to a HashSet while iterating over it. This makes what you are trying to do slightly awkward. The line

element = element.replaceAll("[^a-zA-Z0-9]", "");

gives a new string, but the new string won't be in the set.

You can do it like this:

private static void reduceVocab(HashSet<String> vocab) {
Set<String> copy = new HashSet<>();
for (String str : vocab) {
str = str.replaceAll("[^a-zA-Z0-9]", "");
if (str.length() > 3)
copy.add(str);
}
vocab.clear();
vocab.addAll(copy);
}


Related Topics



Leave a reply



Submit