Pergunta

Eu tenho um hashset em C # que eu estou retirando se uma condição for atendida durante a iteração embora o hashset e não pode fazer isso usando um loop foreach como abaixo.

foreach (String hashVal in hashset) 
{
     if (hashVal == "somestring") 
     {
            hash.Remove("somestring");
     }
}

Então, como posso remover elementos, enquanto a iteração?

Foi útil?

Solução

Use a RemoveWhere método de HashSet em vez disso:

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

Você especifica uma condição / predicado como o parâmetro para o método. Qualquer item na hashset que coincide com o predicado serão removidos.

Isso evita o problema de modificar a hashset enquanto ele está sendo iterado.


Em resposta ao seu comentário:

's' representa o item atual que está sendo avaliada a partir de dentro do hashset.

O código acima é equivalente a:

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

ou

hashset.RemoveWhere(ShouldRemove);

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

EDIT: Algo acaba de me ocorreu: desde HashSet é um conjunto que não contém valores duplicados, apenas chamando hashset.Remove("somestring") será suficiente. Não há necessidade de fazê-lo em um loop como nunca haverá mais do que um jogo.

Outras dicas

Você não pode remover itens de uma coleção ao loop sobre ele com um enumerador. Duas abordagens para resolver este são:

  • para trás loop sobre a coleção usando um regular indexados for-loop (que eu acredito que não é uma opção no caso de um HashSet)
  • loop sobre a coleção, adicionar itens a serem removidos para outra coleção, então varrer o -collection "a-ser-excluído" e remover os itens:

Exemplo da segunda abordagem:

HashSet<string> hashSet = new HashSet<string>();
hashSet.Add("one");
hashSet.Add("two");

List<string> itemsToRemove = new List<string>();
foreach (var item in hashSet)
{
    if (item == "one")
    {
        itemsToRemove.Add(item);
    }
}

foreach (var item in itemsToRemove)
{
    hashSet.Remove(item);
}

Gostaria de evitar o uso de loop dois foreach - um loop foreach é suficiente:

HashSet<string> anotherHashSet = new HashSet<string>();
foreach (var item in hashSet)
{
    if (!shouldBeRemoved)
    {
        anotherSet.Add(item);
    }
}
hashSet = anotherHashSet;

Normalmente, quando eu quero iterar sobre os valores algo e remover eu uso:

 For (index = last to first)
      If(ShouldRemove(index)) Then
           Remove(index)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top