.NET SortedSet出现故障时删除项目... [英] Removing items when a .NET SortedSet goes out of order...

查看:80
本文介绍了.NET SortedSet出现故障时删除项目...的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

有谁知道一种方法来从.NET sortedset中删除出现故障的项吗?

在您跳起来告诉我排序后的集合不会失序之前,所有需要发生的事情就是对排序后的集合中的对象进行参数更改(对集合进行排序).

例如,假设我们有一个Person类,该类具有可修改的名称"字段,并且有一个sortedset< person>包含许多人,并按名称排序.

hi everybody,

does anybody know of a way to remove an item from a .NET sortedset when it falls out of order?

Before you jump to tell me that a sorted set cannot fall out of order, all that needs to happen is for an object in the sorted set to have a parameter (by which the set is sorted) altered.

For example, imagine if we have a Person class with a modifiable ''Name'' field, and a sortedset<person> that contains many people, and is sorted by Name.

[0]"April"
[1]"Bob"
[2]"Mary"
[3]"Zelda"


如果我们将项目0(4月)的名称更改为"Zoe",它将保留在位置0:


If we change the name of item 0 (April) to "Zoe", it will remain at position 0:

[0]"Zoe"
[1]"Bob"
[2]"Mary"
[3]"Zelda"


我尝试过的:
我试图让项目引发事件,以便当这些字段发生更改(例如名称)时,sortedset将找到该项目,将其删除,然后重新插入,因此它应该以正确的顺序排列.但是,这不起作用,因为sortedset乱序时无法找到/删除项目:大概是其二进制搜索方法停止了工作.我找不到让您从特定索引中删除项目的方法.
我也像这样尝试过RemoveWhere()方法,但仍然找不到项目:


What I have tried:
I tried to get the items to fire an event so that when these fields changed ( e.g. Name), the sortedset would find the item, remove it, and then reinsert it, So it should be in the right order. This doesn''t work, though, because the sortedset cannot find/remove items when it is out of order: presumably its binary search method stops working. I can''t find a method which lets you remove items from a specific index.
I have also tried the RemoveWhere() method like so, but it still doesn''t find the items:

public void RemoveSafe(T removeMe)
{
    //removes an item, even if it is out of sort order
    RemoveWhere(a => a == removeMe);
}


当然,另一种解决方案是删除一项,对其进行修改,然后再将其重新添加.排序条件比上面的Person示例复杂了数十亿倍,并且此解决方案的确使它变得非常凌乱...

因此,重申一下:
有谁知道一种在排序混乱的项目中将其从排序集中删除的方法吗?

也欢迎其他想法:)
谢谢!


an alternate solution, of course, is to remove an item, modify it, then add it back in. Unfortunately my program & sorting criteria is a bazillion times more complex than the Person example above, and this solution would make it very messy indeed...

So, to reiterate:
does anybody know of a way to remove an item from a sorted set when it falls out of order?

Other ideas also welcome :)
Thanks!

推荐答案

问题是由于Person的值更改与比较有关而引起的,而SortedSet却不知道该值已经改变.我找不到解决此问题的方法.
我尝试了以下代码(为其他人澄清了问题所在:

The problem arises from the fact that the Person has a value changed that is involved with the comparison, but the SortedSet is unaware the value has changed. I couldn''t find a way to fix this.
I tried the following code (to clarify for others what the problem is :

class Person:  IComparable
{
    public string Name { get; set; }

    public int CompareTo(object obj)
    {
        //Not robust code!
        Person objPerson = obj as Person;
        return this.Name.CompareTo(objPerson.Name);
    }

    public Person(string name)
    {
        Name = name;
    }      
}

class Program
{
    static SortedSet<person> sortedSet = new SortedSet<person>();

    static void WriteElements()
    {
        foreach (Person foo in sortedSet)
            Console.WriteLine(foo.Name);
    }

    static void Main(string[] args)
    {
        Person alice = new Person("Alice"); 
        sortedSet.Add(new Person("Zelda"));
        sortedSet.Add(new Person("Bob"));
        sortedSet.Add(new Person("Mary"));
        sortedSet.Add(alice);
        alice.Name = "Zoe";
        WriteElements();
        Console.ReadKey();
    }
}



可悲的是,看来Microsoft尚未给我们提供一种方法来强制对套件进行重新排序以对其进行修复.
文档中没有任何内容告诉您不应以这种方式更改属性,这似乎是非常合理的事情.您可以向他们提出此要求,因为它看起来像是真正的错误!

我的解决方案是从列表中删除该项目,对其进行更新,然后暂时重新插入.希望有人有更好的答案!


迈克·汉基 [



Sadly, it looks like Microsoft have not given us a way to force the set to re-sort which would fix it.
There is nothing in the documentation telling you shouldn''t change the properties in this way and it seems a very reasonable thing to do. You could raise this with them as it looks like a genuine bug!

My solution is to remove the item from the list, update it then re-insert for now. I hope someone has a better answer!


Mike Hankey[^] has found a work around you can look at. It looks an option, if you don''t mind the INotify... and IObservable... stuff


,这是一个选择,这是一个有趣的发现.还与SortedSet一起玩了一段时间,遇到了同样的问题.

我发现的唯一发现是,该文档使IComparer接口的内容非常混乱.据说comparer属性提供了IEqualityComparer接口,但似乎是IEquality.我尝试为比较器实现两个接口,但没有任何变化.

猜猜当前这会导致重新创建和替换整个集合,或者导致在集合外部进行排序,例如,在HashSet上使用LINQ.

我也发现BOL中的这句话可能是一个夸大的陈述:"在插入和删除元素时,sortedSet< T>维持排序顺序,而不会影响性能":)
This was an interesting finding. Also played with the SortedSet for a while and encountered the same problem.

The only thing I found was that the documentation was quite confusing what comes to the IComparer interface. The comparer property is said to give the IEqualityComparer interface, but seems that it''s the IEquality instead. I tried implementing both interfaces for the comparer, but no change.

Guess that currently this leads to either recreating and replacing the whole set or making the ordering outside a collection, for example using LINQ over HashSet.

Also I find this statement in BOL likely to be an overstatement "A SortedSet <T> maintains a sorted order as elements are inserted and deleted without affecting performance" :)


我认为没有任何简单而优雅的解决方案. SortedSet在内部使用二叉树,而二叉搜索树在其结构被破坏时根本不起作用.

我最好的建议是:永远不要使SortedSet混乱.您可能需要稍微更改应用程序逻辑,使用其他集合,甚至实现自己的SortedSomething类...
I don''t think there is any alegant and simple solution. SortedSet uses a binary tree internally and a binary search tree simply doesn''t work when its structure is broken.

My best advice is: do never, ever make SortedSet fall out of order. You may have to change your application logic a bit, use a different collection or even implement your own SortedSomething class...


这篇关于.NET SortedSet出现故障时删除项目...的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆