繁体   English   中英

迭代时从哈希集中删除

[英]Remove from hashset while iterating

我有以下代码:

       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分别是第一层和第二层上重复作者的大小。 我必须经常删除这些项目,并且数组的大小很大。 因此,该算法效率很低。 实际上,我具有以下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();
        }
    }
}
}

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

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

您在这里所做的操作有误,原因有两个: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);
       }
   }

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

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

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

考虑以下:

        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

现在,如果您要确保哈希集A在哈希集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中的项目

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM