/Sets/Extensions.cs |
@@ -0,0 +1,69 @@ |
/////////////////////////////////////////////////////////////////////////// |
// 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 |
{ |
/// <summary> |
/// 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. |
/// </summary> |
/// <typeparam name="T">the type o the collection</typeparam> |
/// <param name="o">the first sequence to remove from</param> |
/// <param name="p">the second sequence to remove</param> |
/// <returns>the first sequence excluding the second sequence or the second sequence excluding the first sequence</returns> |
public static IEnumerable<T> SequenceExceptAny<T>(this IEnumerable<T> o, IEnumerable<T> p) where T : IEquatable<T> |
{ |
var l = new List<T>(o); |
var r = new List<T>(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))); |
} |
|
/// <summary> |
/// Sequentially removes all the elements from the first sequence that are in the second sequence. |
/// </summary> |
/// <typeparam name="T">the type o the collection</typeparam> |
/// <param name="o">the first sequence to remove from</param> |
/// <param name="p">the second sequence to remove</param> |
/// <returns>the first sequence excluding the second sequence</returns> |
public static IEnumerable<T> SequenceExcept<T>(this IEnumerable<T> a, IEnumerable<T> b) where T : IEquatable<T> |
{ |
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; |
} |
} |
} |
} |
|
/// <summary> |
/// Determines whether a sequence is contained within another sequence. |
/// </summary> |
/// <returns>true if and only if the first set is contained in the second set</returns> |
/// <param name="a">The set to check</param> |
/// <param name="b">The set to check against</param> |
/// <typeparam name="T">the set type</typeparam> |
public static bool SubsetEquals<T>(this IEnumerable<T> a, IEnumerable<T> b) where T : IEquatable<T> => |
!a.OrderBy(s => s).SequenceExcept(b.OrderBy(s => s)).Any(); |
} |
} |