迭代时从hashset中删除

时间:2014-03-18 09:14:33

标签: c# iteration hashset remove-if

我有以下代码:

       List<HashSet<String>> authorLists = new List<HashSet<String>>
       // fill it
        /** Remove duplicate authors  */
        private void removeDublicateAuthors(HashSet<String> newAuthors, int curLevel)
        {

            for (int i = curLevel - 1; i > 0; --i)
            {
                HashSet<String> authors = authorLists[i];
                foreach (String item in newAuthors)
                {
                    if (authors.Contains(item))
                    {
                        newCoauthors.Remove(item);
                    }
                }
            }
        }

如何正确删除商品?我需要遍历newAuthors和authorLists。由于这个原因,RemoveWhere不能在这里使用。

创建新列表,向其添加项目然后删除重复项目效率非常低。就我而言,authorLists列表具有以下大小:

authorLists [0].size = 0;
authorLists [1].size = 322;
authorLists [2].size = 75000; // (even more than this value)

我需要调用removeDublicateAuthors 1 *(1) 322 (n) 75000 (m)次,其中n和m是1和1的重复作者的大小相应的第二级。我必须经常删除这些项目,并且数组的大小非常大。因此,该算法效率很低。 实际上我在Java中有以下代码,并且由于某些原因重写它:

/ **删除作者树中的重复作者* /

private void removeDublicateAuthors(HashSet<String> newCoauthors, int curLevel ) {

for(int i = curLevel - 1; i > 0; --i) {
    HashSet<String> authors = coauthorLevels.get(i);
    for (Iterator<String> iter = newCoauthors.iterator(); iter.hasNext();) {
        iter.next();
        if(authors.contains(iter)) {
            iter.remove();
        }
    }
}
}

目前它的工作速度比建议的选项快得多

4 个答案:

答案 0 :(得分:3)

您可以在另一个哈希集中添加要删除的项目,然后将其全部删除。

答案 1 :(得分:1)

你在这里做的是错误的,原因有两个:  1.你不能改变你正在解析的集合 - sintax问题  2.即使您使代码工作,您也只会改变值,而不是参考 - 逻辑问题

   List<HashSet<String>> authorLists = new List<HashSet<String>>
   // fill it
   /** Remove duplicate authors  */
   // handle reference instead of value
   private void removeDublicateAuthors(ref HashSet<String> newAuthors, int curLevel)
   {
       List<string> removeAuthors = new List<string>();

       for (int i = curLevel - 1; i > 0; --i)
       {
           HashSet<String> authors = authorLists[i];
           foreach (String item in newAuthors)
           {
               if (authors.Contains(item))
               {
                   removeAuthors .Add(item);
               }
           }
       }

       foreach(string author in removeAuthors)
       {
           newAuthors.Remove(author);
       }
   }

答案 2 :(得分:0)

您正在寻找的是ExceptWith。您正试图找到从另一个集合中减去的一组集合,这正是该方法的作用。

答案 3 :(得分:-1)

如果我不明白你想要做什么,请原谅我。

散列集不允许重复,因为项的索引是项的散列。两个相等的字符串将具有相同的散列,因此具有相同的索引。因此,如果您只是组合任意两个哈希集,则结果不会重复。

请考虑以下事项:

        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);   
        }

此代码的输出为:

foo

现在,如果您正在尝试确保hashset A不包含hashset B中的任何项目,那么您可以执行以下操作:

        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);    
        }

其输出为:

bar

考虑到这一点,您可以使用.Except方法从另一个集合中减去一个集合。

var set3 = set1.Except(set2);

这将生成set1中不在set2

中的所有项目