using System; using System.Collections.Generic; using System.Collections.ObjectModel; namespace ZymonicServices; /// Applies a unique sequence of object instances without resetting a bound collection. /// Call on the thread which owns the collection. public static class ZymonicCollectionProjection { public static void Apply(ObservableCollection target, IReadOnlyList desired) where T : class { var retained = new HashSet(desired, ReferenceEqualityComparer.Instance); if (retained.Count != desired.Count) throw new ArgumentException("Projection must contain unique instances.", nameof(desired)); for (int i = target.Count - 1; i >= 0; i--) if (!retained.Contains(target[i])) target.RemoveAt(i); for (int i = 0; i < desired.Count; i++) { if (i < target.Count && ReferenceEquals(target[i], desired[i])) continue; int existing = -1; for (int j = i + 1; j < target.Count; j++) { if (ReferenceEquals(target[j], desired[i])) { existing = j; break; } } if (existing >= 0) target.Move(existing, i); else target.Insert(i, desired[i]); } while (target.Count > desired.Count) target.RemoveAt(target.Count - 1); } }