/// <summary> /// Union /// </summary> public static MultiHashSet <T> Union <T>(this MultiHashSet <T> left, MultiHashSet <T> right) { if (left is null) { throw new ArgumentNullException(nameof(left)); } else if (right is null) { throw new ArgumentNullException(nameof(right)); } MultiHashSet <T> result = new(left.Comparer); foreach (var leftPair in left.Items) { long count = leftPair.Value + right[leftPair.Key]; result.Add(leftPair.Key, Math.Min(leftPair.Value, count)); } foreach (var rightPair in right.Items) { if (!left.Contains(rightPair.Key)) { result.Add(rightPair.Key, rightPair.Value); } } return(result); }
/// <summary> /// Equals /// </summary> public bool Equals(MultiHashSet <T> other) { if (ReferenceEquals(this, other)) { return(true); } else if (other is null) { return(false); } if (m_Items.Count != other.m_Items.Count) { return(false); } foreach (var pair in m_Items) { if (!m_Items.TryGetValue(pair.Key, out long otherCount) || otherCount != pair.Value) { return(false); } } return(true); }
/// <summary> /// Intersect /// </summary> public static MultiHashSet <T> Intersect <T>(this MultiHashSet <T> left, MultiHashSet <T> right) { if (left is null) { throw new ArgumentNullException(nameof(left)); } else if (right is null) { throw new ArgumentNullException(nameof(right)); } MultiHashSet <T> result = new(left.Comparer); foreach (var leftPair in left.Items) { long rightCount = right[leftPair.Key]; if (rightCount > 0) { result.Add(leftPair.Key, Math.Min(leftPair.Value, rightCount)); } } return(result); }
/// <summary> /// If proper subset of /// </summary> public bool IsProperSubsetOf(MultiHashSet <T> other) { if (other is null) { throw new ArgumentNullException(nameof(other)); } bool proper = false; foreach (var pair in m_Items) { long currentCount = pair.Value; long otherCount = other[pair.Key]; if (otherCount < currentCount) { return(false); } else if (otherCount > currentCount) { proper = true; } } return(proper); }
/// <summary> /// Symmetric Except with /// </summary> public void SymmetricExceptWith(MultiHashSet <T> other) { if (other is null) { throw new ArgumentNullException(nameof(other)); } foreach (var pair in other.m_Items) { if (m_Items.TryGetValue(pair.Key, out long value)) { value -= pair.Value; if (value == 0) { m_Items.Remove(pair.Key); } else { m_Items[pair.Key] = Math.Abs(value); } } else { m_Items.Add(pair.Key, pair.Value); } } }
/// <summary> /// Symmetric Except /// </summary> public static MultiHashSet <T> SymmetricExcept <T>(this MultiHashSet <T> left, MultiHashSet <T> right) { if (null == left) { throw new ArgumentNullException(nameof(left)); } else if (null == right) { throw new ArgumentNullException(nameof(right)); } MultiHashSet <T> result = new MultiHashSet <T>(left.Comparer); foreach (var leftPair in left.Items) { long count = leftPair.Value - right[leftPair.Key]; if (count != 0) { result.Add(leftPair.Key, Math.Min(leftPair.Value, Math.Abs(count))); } } foreach (var rightPair in right.Items) { if (!left.Contains(rightPair.Key)) { result.Add(rightPair.Key, rightPair.Value); } } return(result); }
/// <summary> /// If proper superset of /// </summary> public bool IsProperSupersetOf(MultiHashSet <T> other) { if (other is null) { throw new ArgumentNullException(nameof(other)); } return(other.IsProperSubsetOf(this)); }
/// <summary> /// If subset of /// </summary> public bool IsSubsetOf(MultiHashSet <T> other) { if (other is null) { throw new ArgumentNullException(nameof(other)); } foreach (var pair in m_Items) { if (other[pair.Key] < pair.Value) { return(false); } } return(true); }
/// <summary> /// Union with /// </summary> public void UnionWith(MultiHashSet <T> other) { if (other is null) { throw new ArgumentNullException(nameof(other)); } foreach (var pair in other.m_Items) { if (m_Items.TryGetValue(pair.Key, out long value)) { m_Items[pair.Key] = value + pair.Value; } else { m_Items.Add(pair.Key, pair.Value); } } }
/// <summary> /// If sequencies are equal as multisets /// </summary> public static bool MultiSetEqual <T>(this IEnumerable <T> source, IEnumerable <T> other, IEqualityComparer <T> comparer) { if (ReferenceEquals(source, other)) { return(true); } else if (null == source) { return(false); } else if (null == other) { return(false); } var left = new MultiHashSet <T>(source, comparer); var right = new MultiHashSet <T>(other, comparer); return(left.Equals(right)); }
/// <summary> /// Intersect with /// </summary> public void IntersectWith(MultiHashSet <T> other) { if (other is null) { throw new ArgumentNullException(nameof(other)); } var list = m_Items.ToList(); foreach (var item in list) { long count = Math.Min(item.Value, other[item.Key]); if (count <= 0) { m_Items.Remove(item.Key); } else { m_Items[item.Key] = count; } } }
/// <summary> /// Except with /// </summary> public void ExceptWith(MultiHashSet <T> other) { if (null == other) { throw new ArgumentNullException(nameof(other)); } foreach (var pair in other.m_Items) { if (m_Items.TryGetValue(pair.Key, out long value)) { value -= pair.Value; if (value <= 0) { m_Items.Remove(pair.Key); } else { m_Items[pair.Key] = value; } } } }