/// <summary> /// Check if all items in a supplied collection is in this bag /// (counting multiplicities). /// </summary> /// <param name="items">The items to look for.</param> /// <returns>True if all items are found.</returns> public virtual bool ContainsAll(SCG.IEnumerable <T> items) { HashBag <T> res = new HashBag <T>(itemequalityComparer); foreach (T item in items) { if (res.ContainsCount(item) < ContainsCount(item)) { res.Add(item); } else { return(false); } } return(true); }
/// <summary> /// Remove all items *not* in a supplied collection from this bag, /// counting multiplicities. /// </summary> /// <param name="items">The items to retain</param> public virtual void RetainAll(SCG.IEnumerable <T> items) { updatecheck(); HashBag <T> res = new HashBag <T>(itemequalityComparer); foreach (T item in items) { KeyValuePair <T, int> p = new KeyValuePair <T, int>(item); if (dict.Find(ref p)) { KeyValuePair <T, int> q = p; if (res.dict.Find(ref q)) { if (q.Value < p.Value) { q.Value++; res.dict.Update(q); res.size++; } } else { q.Value = 1; res.dict.Add(q); res.size++; } } } if (size == res.size) { return; } CircularQueue <T> wasRemoved = null; if ((ActiveEvents & EventTypeEnum.Removed) != 0) { wasRemoved = new CircularQueue <T>(); foreach (KeyValuePair <T, int> p in dict) { int removed = p.Value - res.ContainsCount(p.Key); if (removed > 0) #warning We could send bag events here easily using a CircularQueue of (should?) { for (int i = 0; i < removed; i++) { wasRemoved.Enqueue(p.Key); } } } } dict = res.dict; size = res.size; if ((ActiveEvents & EventTypeEnum.Removed) != 0) { raiseForRemoveAll(wasRemoved); } else if ((ActiveEvents & EventTypeEnum.Changed) != 0) { raiseCollectionChanged(); } }
public virtual void RetainAll <U>(SCG.IEnumerable <U> items) where U : T { updatecheck(); HashBag <T> res = new HashBag <T>(ItemEqualityComparer); foreach (U item in items) { Multiplicity <T> p = new Multiplicity <T>(item); if (dict.Find(ref p)) { Multiplicity <T> q = p; if (res.dict.Find(ref q)) { if (q.Count < p.Count) { q.Count++; res.dict.Update(q); res.Size++; } } else { q.Count = 1; res.dict.Add(q); res.Size++; } } } if (Size == res.Size) { return; } CircularQueue <T> wasRemoved = null; if ((ActiveEvents & EventTypeEnum.Removed) != 0) { wasRemoved = new CircularQueue <T>(); foreach (Multiplicity <T> p in dict) { int removed = p.Count - res.ContainsCount(p.Value); if (removed > 0) #warning We could send bag events here easily using a CircularQueue of (should?) { for (int i = 0; i < removed; i++) { wasRemoved.Enqueue(p.Value); } } } } dict = res.dict; Size = res.Size; if ((ActiveEvents & EventTypeEnum.Removed) != 0) { raiseForRemoveAll(wasRemoved); } else if ((ActiveEvents & EventTypeEnum.Changed) != 0) { raiseCollectionChanged(); } }