我有ObservableCollection a和List b
现在我想从集合中删除列表b中具有等价物的元素.
public static void CrossRemove<TFirst,TSecond>(this ObservableCollection<TFirst> collection,IEnumerable<TSecond> secondCollection,Func<TFirst,TSecond,bool> predicate) { collection.Where(first => secondCollection.Any(second => predicate(first,second))) .ToList().ForEach(item => collection.Remove(item)); }
用法:
ObservableCollection<string> first = new ObservableCollection<string> { "1","2","3","4","5","6","k" }; IEnumerable<int> second = new List<int> { 2,3,5 }; first.CrossRemove(second,(x,y) => x == y.ToString());
此代码从集合中删除“2”,“3”和“5”,留下“1”,“4”,“6”和“k”.
在我的真实代码中,a和b包含从相同接口继承的元素,我正在比较该接口中的属性,但我无法对它进行任何冒险.
我不能创建一个新的列表,因为它绑定到wpf视图,如果我这样做而不是删除项目将会出现可见的故障.
有没有更好/更快的方法呢?
解决方法
您可以将第二个集合设为
HashSet<T>
,以便更快地进行查找.我也更改了你的
ForEach
to a foreach
.这更容易用属性来演示,就像在原版中一样.
void Main() { ObservableCollection<MyClass> first = new ObservableCollection<MyClass> { "1","k" }; ISet<IMyInterface> second = new HashSet<IMyInterface>(new MyClass2[] { 2,5 },new MyEqualityComparer()); first.CrossRemove(second); Console.WriteLine(string.Join(",",first.Select(x => x.MyProperty))); // 1,4,6,k } public interface IMyInterface { string MyProperty { get; set; } } public class MyEqualityComparer : IEqualityComparer<IMyInterface> { public bool Equals(IMyInterface a,IMyInterface b) { return a.MyProperty == b.MyProperty; } public int GetHashCode(IMyInterface obj) { return obj.MyProperty.GetHashCode(); } } public static class Extensions { public static void CrossRemove<TFirst,ISet<TSecond> set) where TFirst : TSecond { foreach (var item in collection.Where(item => set.Contains(item)).ToList()) collection.Remove(item); } } public class MyClass : IMyInterface { public string MyProperty { get; set; } public static implicit operator MyClass(string s) { return new MyClass { MyProperty = s }; } } public class MyClass2 : IMyInterface { public string MyProperty { get; set; } public static implicit operator MyClass2(int i) { return new MyClass2 { MyProperty = i.ToString() }; } }
即使对象不共享公共接口,您也应该能够编写IEqualityComparer< object>适用于两者,例如如果你的lambda谓词是:
(TypeA a,TypeB b) => a.PropA == b.PropB
然后你的课将是:
public class MyOtherEqualityComparer : IEqualityComparer<object> { private object GetProperty(object obj) { if (obj is TypeA) return ((TypeA)obj).PropA; else if (obj is TypeB) return ((TypeB)obj).PropB; else throw new Exception(); } public bool Equals(object a,object b) { return GetProperty(a).Equals(GetProperty(b)); } public int GetHashCode(object obj) { return GetProperty(obj).GetHashCode(); } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。