加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 从ObservableCollection项中删除名称出现在其他列表中的项

发布时间:2020-12-15 21:58:09 所属栏目:百科 来源:网络整理
导读:我有ObservableCollection a和List b 现在我想从集合中删除列表b中具有等价物的元素. 我的代码在这一刻: public static void CrossRemoveTFirst,TSecond(this ObservableCollectionTFirst collection,IEnumerableTSecond secondCollection,FuncTFirst,TSeco
我有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();
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读