C# 对复合集合进行排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-07-31 17:38:34  来源:igfitidea点击:

Sorting a composite collection

提问by Christopher Scott

So WPF doesn't support standard sorting or filtering behavior for views of CompositeCollections, so what would be a best practice for solving this problem.

所以 WPF 不支持 CompositeCollections 视图的标准排序或过滤行为,那么解决这个问题的最佳实践是什么。

There are two or more object collections of different types. You want to combine them into a single sortable and filterable collection (withing having to manually implement sort or filter).

有两个或多个不同类型的对象集合。您想将它们组合成一个可排序和可过滤的集合(而不必手动实现排序或过滤)。

One of the approaches I've considered is to create a new object collection with only a few core properties, including the ones that I would want the collection sorted on, and an object instance of each type.

我考虑过的方法之一是创建一个只有几个核心属性的新对象集合,包括我希望对集合排序的那些,以及每种类型的对象实例。

class MyCompositeObject
{
    enum           ObjectType;
    DateTime       CreatedDate;
    string         SomeAttribute;
    myObjectType1  Obj1;
    myObjectType2  Obj2;
{
class MyCompositeObjects : List<MyCompositeObject> { }

And then loop through my two object collections to build the new composite collection. Obviously this is a bit of a brute force method, but it would work. I'd get all the default view sorting and filtering behavior on my new composite object collection, and I'd be able to put a data template on it to display my list items properly depending on which type is actually stored in that composite item.

然后循环遍历我的两个对象集合以构建新的复合集合。显然,这是一种蛮力方法,但它会起作用。我会在我的新复合对象集合上获得所有默认的视图排序和过滤行为,并且我将能够在其上放置一个数据模板以根据实际存储在该复合项目中的类型正确显示我的列表项目。

What suggestions are there for doing this in a more elegant way?

有什么建议可以以更优雅的方式做到这一点?

采纳答案by Christopher Scott

Update: I found a much more elegant solution:

更新:我找到了一个更优雅的解决方案:

class MyCompositeObject
{
    DateTime    CreatedDate;
    string      SomeAttribute;
    Object      Obj1;
{
class MyCompositeObjects : List<MyCompositeObject> { }

I found that due to reflection, the specific type stored in Obj1 is resolved at runtime and the type specific DataTemplate is applied as expected!

我发现由于反射,存储在 Obj1 中的特定类型在运行时解析,并且按预期应用类型特定的 DataTemplate!

回答by lubos hasko

"Brute force" method you mention is actually ideal solution. Mind you, all objects are in RAM, there is no I/O bottleneck, so you can pretty much sort and filter millions of objects in less than a second on any modern computer.

您提到的“蛮力”方法实际上是理想的解决方案。请注意,所有对象都在 RAM 中,没有 I/O 瓶颈,因此您几乎可以在任何现代计算机上在不到一秒钟的时间内对数百万个对象进行排序和过滤。

The most elegant way to work with collections is System.Linq namespace in .NET 3.5

使用集合最优雅的方式是 .NET 3.5 中的 System.Linq 命名空间

Thanks - I also considered LINQ to objects, but my concern there is loss of flexibility for typed data templates, which I need to display the objects in my list.

谢谢 - 我也考虑过 LINQ to objects,但我担心类型化数据模板会失去灵活性,我需要在我的列表中显示对象。

If you can't predict at this moment how people will sort and filter your object collection, then you should look at System.Linq.Expressionsnamespace to build your lambda expressions on demand during runtime (first you let user to build expression, then compile, run and at the end you use reflection namespace to enumerate through results). It's more tricky to wrap your head around it but invaluable feature, probably (to me definitively) even more ground-breaking feature than LINQ itself.

如果此时您无法预测人们将如何对您的对象集合进行排序和过滤,那么您应该查看System.Linq.Expressions命名空间以在运行时按需构建 lambda 表达式(首先让用户构建表达式,然后编译, 运行并在最后使用反射命名空间来枚举结果)。将你的头脑围绕在它周围更棘手,但它是无价的功能,可能(对我来说绝对)比 LINQ 本身更具开创性的功能。

回答by Brian Ensink

I'm not yet very familiar with WPF but I see this as a question about sorting and filtering List<T>collections.

我对 WPF 还不是很熟悉,但我认为这是一个关于排序和过滤List<T>集合的问题。

(withing having to manually implement sort or filter)

(无需手动实现排序或过滤)

Would you reconsider implementing your own sort or filter functions? In my experience it is easy to use. The examples below use an anonymous delegate but you could easily define your own method or a class to implement a complex sort or filter. Such a class could even have properties to configure and change the sort and filter dynamically.

您会重新考虑实现自己的排序或过滤功能吗?根据我的经验,它很容易使用。下面的示例使用匿名委托,但您可以轻松定义自己的方法或类来实现复杂的排序或过滤器。这样的类甚至可以具有动态配置和更改排序和过滤器的属性。

Use List<T>.Sort(Comparison<T> comparison)with your custom compare function:

使用List<T>.Sort(Comparison<T> comparison)与您的自定义比较函数:

// Sort according to the value of SomeAttribute
List<MyCompositeObject> myList = ...;
myList.Sort(delegate(MyCompositeObject a, MyCompositeObject b) 
{
    // return -1 if a < b
    // return 0 if a == b
    // return 1 if a > b
    return a.SomeAttribute.CompareTo(b.SomeAttribute);
};

A similar approach for getting a sub-collection of items from the list.

从列表中获取项目子集合的类似方法。

Use List<T>.FindAll(Predicate<T> match)with your custom filter function:

使用List<T>.FindAll(Predicate<T> match)与您的自定义过滤功能:

// Select all objects where myObjectType1 and myObjectType2 are not null
myList.FindAll(delegate(MyCompositeObject a)
{
    // return true to include 'a' in the sub-collection
    return (a.myObjectType1 != null) && (a.myObjectType2 != null);
}