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 TSource ExclusiveOrDefault(this IEnumerable source) { if (source == null) { throw new ArgumentNullException("source"); } var results = source.Take(2).ToArray(); return results.Length == 1 ? results[0] : default(TSource); } public static TSource ExclusiveOrDefault(this IEnumerable source, Func predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var results = source.Where(predicate).Take(2).ToArray(); return results.Length == 1 ? results[0] : default(TSource); } 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 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 TSource MostCommon(this IEnumerable items) { return items.GroupBy(x => x).OrderByDescending(x => x.Count()).First().Key; } public static TResult MostCommon(this IEnumerable items, Func predicate) { return items.Select(predicate).GroupBy(x => x).OrderByDescending(x => x.Count()).First().Key; } } }