Can I write these functions more efficient?
public static void AddDistinct<T>(this ICollection<T> sourc开发者_如何学Pythone, params ICollection<T>[] collections)
{
(from collection in collections from item in collection where !source.Contains(item) select item).ForEach(source.Add);
}
public static void AddDistinct<T>(this ICollection<T> source, Func<T, bool> predicate, params ICollection<T>[] collections)
{
collections.ForEach(collection => collection.Where(predicate).Where(item => !source.Contains(item)).ForEach(source.Add));
}
public static void AddDistinct<T>(this ICollection<T> source, params T[] items)
{
items.Where(item => !source.Contains(item)).ForEach(source.Add);
}
public static void AddDistinct<T>(this ICollection<T> source, Func<T, bool> predicate, params T[] items)
{
items.Where(predicate).Where(x => !source.Contains(x)).ForEach(source.Add);
}
You can use the Except
method:
public static void AddDistinct<T>(this ICollection<T> source, params ICollection<T>[] collections)
{
var itemsToAdd = collections.SelectMany(x => x).Where(predicate).Except(source).ToArray();
itemsToAdd.ForEach(source.Add));
}
public static void AddDistinct<T>(this ICollection<T> source, Func<T, bool> predicate, params ICollection<T>[] collections)
{
var itemsToAdd = collections.SelectMany(x => x).Where(predicate).Except(source).ToArray();
itemsToAdd.ForEach(source.Add));
}
public static void AddDistinct<T>(this ICollection<T> source, params T[] items)
{
var itemsToAdd = items.Except(source).ToArray();
itemsToAdd.ForEach(source.Add));
}
public static void AddDistinct<T>(this ICollection<T> source, Func<T, bool> predicate, params T[] items)
{
var itemsToAdd = items.Where(predicate).Except(source).ToArray();
itemsToAdd.ForEach(source.Add));
}
Note that because Where
and Except
have deferred and streamed execution, you need the ToArray()
call to ensure the enumeration of source
is complete before you add anything to it (since a collection can't be modified while it's being enumerated).
Yes, using e.g. a hashset you can do much better than O(N*M)
.
Using HashSet<T>
and IEnumerable<T>
you can do it more efficient I think. The HashSet is efficient at keeping track of duplicates, and you only need to go through the source once to load them into the set. And unless I'm mistaken, I think both ICollection<T>
and T[]
are IEnumerable<T>
s?
public static void AddDistinct<T>(this ICollection<T> source, params IEnumerable<T> items)
{
var set = new HashSet<T>(source);
foreach(var item in items)
{
if(set.Add(item))
source.Add(item);
}
}
Not sure what you need those predicate versions for though. Can't you just filter your items before you add them?
精彩评论