合并两个Collection <T>
我有一个函数,该函数返回一个Collection <string>
,然后递归调用自身,最终返回一个大的Collection <string>
。
现在,我只是想知道合并列表的最佳方法是什么? Collection.CopyTo()
仅复制到string [],使用foreach()
循环感觉效率低下。但是,由于我也想过滤出重复项,所以我觉得我最终会得到一个在Collection
上调用Contains()
的foreach。
我想知道,有没有更有效的方法来使递归函数返回不重复的字符串列表?我不必使用Collection
,它几乎可以是任何合适的数据类型。
仅排除在外,我绑定到Visual Studio 2005和.net 3.0,所以没有LINQ。
编辑:澄清:函数将用户带出Active Directory,查看该用户的直接报告,然后递归查看每个用户的直接报告。因此,最终结果是给定用户"命令链"中所有用户的列表。由于此命令执行得很频繁,并且目前对于某些用户而言需要20秒,因此我正在寻找改进方法。缓存24小时的结果也在我的列表中,但是我想在应用缓存之前先看看如何改进它。
解决方案
回答
我认为HashSet <T>
是一个很大的帮助。
The HashSet<T> class provides high performance set operations. A set is a collection that contains no duplicate elements, and whose elements are in no particular order.
只需向其中添加项目,然后使用CopyTo。
更新:HashSet <T>
在.Net 3.5中
也许我们可以使用Dictionary <TKey,TValue>
。将重复键设置为字典不会引发异常。
回答
如果我们使用的是List <>,则可以使用.AddRange将一个列表添加到另一个列表中。
或者,我们可以使用yield return即时合并列表,如下所示:
public IEnumerable<string> Combine(IEnumerable<string> col1, IEnumerable<string> col2) { foreach(string item in col1) yield return item; foreach(string item in col2) yield return item; }
回答
我们可能想看一下Iesi.Collections和Extended Generic Iesi.Collections(因为第一版是在1.1中制作的,当时还没有泛型)。
扩展Iesi具有一个ISet类,该类恰好充当HashSet:它强制执行唯一成员,并且不允许重复。
Iesi的妙处在于它设置了运算符,而不是用于合并集合的方法,因此我们可以在并集(|),交集(&),XOR(^)等之间进行选择。
回答
我们可以通过引用将Collection传递给方法,以便我们可以向其中添加项目,而不必返回任何内容。如果我们在c#中执行此操作,则可能会是这样。
class Program { static void Main(string[] args) { Collection<string> myitems = new Collection<string>(); myMthod(ref myitems); Console.WriteLine(myitems.Count.ToString()); Console.ReadLine(); } static void myMthod(ref Collection<string> myitems) { myitems.Add("string"); if(myitems.Count <5) myMthod(ref myitems); } }
如@Zooba所述,此处无需通过ref传递,如果我们按值传递也将起作用。
回答
就合并而言:
I wonder, is there a more efficient way to have a recursive function that returns a list of strings without duplicates? I don't have to use a Collection, it can be pretty much any suitable data type.
函数汇编了一个返回值,对吗?我们将提供的列表一分为二,再次调用self(两次),然后合并这些结果。
在合并步骤中,为什么不只是在将每个字符串添加到结果之前进行检查?如果已经存在,请跳过它。
假设我们正在使用排序列表。