using System; using System.Collections.Generic; using System.Linq; namespace NzbDrone.Common.Extensions { public static class EnumerableExtensions { public static IEnumerable IntersectBy(this IEnumerable first, Func firstKeySelector, IEnumerable second, Func secondKeySelector, IEqualityComparer keyComparer) { var keys = new HashSet(second.Select(secondKeySelector), keyComparer); foreach (var element in first) { var key = firstKeySelector(element); // Remove the key so we only yield once if (keys.Remove(key)) { yield return element; } } } public static IEnumerable ExceptBy(this IEnumerable first, Func firstKeySelector, IEnumerable second, Func secondKeySelector, IEqualityComparer keyComparer) { var keys = new HashSet(second.Select(secondKeySelector), keyComparer); var matchedKeys = new HashSet(); foreach (var element in first) { var key = firstKeySelector(element); if (!keys.Contains(key) && !matchedKeys.Contains(key)) { // Store the key so we only yield once matchedKeys.Add(key); yield return element; } } } public static Dictionary ToDictionaryIgnoreDuplicates(this IEnumerable src, Func keySelector) { var result = new Dictionary(); foreach (var item in src) { var key = keySelector(item); if (!result.ContainsKey(key)) { result[key] = item; } } return result; } public static Dictionary ToDictionaryIgnoreDuplicates(this IEnumerable src, Func keySelector, Func valueSelector) { var result = new Dictionary(); foreach (var item in src) { var key = keySelector(item); if (!result.ContainsKey(key)) { result[key] = valueSelector(item); } } return result; } public static void AddIfNotNull(this List source, TSource item) { if (item == null) { return; } source.Add(item); } public static bool Empty(this IEnumerable source) { return !source.Any(); } public static bool None(this IEnumerable source, Func predicate) { return !source.Any(predicate); } public static bool NotAll(this IEnumerable source, Func predicate) { return !source.All(predicate); } public static List SelectList(this IEnumerable source, Func predicate) { return source.Select(predicate).ToList(); } public static IEnumerable DropLast(this IEnumerable source, int n) { if (source == null) { throw new ArgumentNullException("source"); } if (n < 0) { throw new ArgumentOutOfRangeException("n", "Argument n should be non-negative."); } return InternalDropLast(source, n); } private static IEnumerable InternalDropLast(IEnumerable source, int n) { var buffer = new Queue(n + 1); foreach (var x in source) { buffer.Enqueue(x); if (buffer.Count == n + 1) { yield return buffer.Dequeue(); } } } public static string ConcatToString(this IEnumerable source, string separator = ", ") { return string.Join(separator, source.Select(x => x.ToString())); } public static string ConcatToString(this IEnumerable source, Func predicate, string separator = ", ") { return string.Join(separator, source.Select(predicate)); } public static HashSet ToHashSet(this IEnumerable source, IEqualityComparer comparer = null) { return new HashSet(source, comparer); } } }