/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // // rights of fair usage, the disclaimer and warranty conditions. // /////////////////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.Linq; namespace wasSharp.Sets { public static class Extensions { /// /// Sequentially removes all the elements from the first sequence that are in the second sequence /// or all the elements from the second sequence that are in the first sequence. /// /// the type o the collection /// the first sequence to remove from /// the second sequence to remove /// the first sequence excluding the second sequence or the second sequence excluding the first sequence public static IEnumerable SequenceExceptAny(this IEnumerable o, IEnumerable p) where T : IEquatable { var l = new List(o); var r = new List(p); return l.Count() > r.Count() ? l.Zip(r, (x, y) => x.Equals(y) ? default(T) : y) .Concat(l.Skip(r.Count())) .Where(q => q != null && !q.Equals(default(T))) : r.Zip(l, (x, y) => x.Equals(y) ? default(T) : y) .Concat(r.Skip(l.Count())) .Where(q => q != null && !q.Equals(default(T))); } /// /// Sequentially removes all the elements from the first sequence that are in the second sequence. /// /// the type o the collection /// the first sequence to remove from /// the second sequence to remove /// the first sequence excluding the second sequence public static IEnumerable SequenceExcept(this IEnumerable a, IEnumerable b) where T : IEquatable { using (var ea = a.GetEnumerator()) { using (var eb = b.GetEnumerator()) { while (ea.MoveNext()) { if (eb.MoveNext() && ea.Current.Equals(eb.Current)) continue; yield return ea.Current; } } } } /// /// Determines whether a sequence is contained within another sequence. /// /// true if and only if the first set is contained in the second set /// The set to check /// The set to check against /// the set type public static bool SubsetEquals(this IEnumerable a, IEnumerable b) where T : IEquatable => !a.OrderBy(s => s).SequenceExcept(b.OrderBy(s => s)).Any(); } }