【问题标题】:Performing filtering and sorting on the original collection对原始集合进行过滤和排序
【发布时间】:2013-05-11 02:46:46
【问题描述】:

我陷入了这样一个场景,即我有一个继承 ICollection 接口形式的自定义集合类,并且我有一个如下代码段:

myCustomCollectionObject.Where(obj=>obj.isValid).ToList().Sort(mycustomerComparer);

以上代码过滤原始集合,然后对集合进行排序 现在在这种情况下,排序将在不同的集合而不是原始集合上执行。

那么,有什么方法或解决方法可以实现先过滤然后对原始集合进行排序

【问题讨论】:

  • myCustomCollectionObject是什么类型?
  • 为什么要过滤,然后然后排序?为什么不能对原始集合进行排序,然后过滤?
  • @RowlandShaw 我想过滤,因为由于某些业务逻辑,集合有一些空行或无效行我们有 2000 个可能为空的静态行和其他业务逻辑
  • 您如何存储您收藏的元素? private List<T> 之类的东西?
  • @YogeshJoshi 您无论如何都希望修改您的初始收藏(即重新排序)。那么现在为什么不做OrderBy 并重新分配呢?还是您的意思是您需要通过忽略其中的某些项目来重新订购?

标签: c# linq sorting filtering


【解决方案1】:

如果你不能使用 Linq 的不可变/功能优点,那么你就必须走老路:

//Remove unwanted items
for (int i = myCustomCollectionObject.Length; i >= 0 ; i--)
{
    if(!myCustomCollectionObject[i].IsValid)
        myCustomCollectionObject.Remove(myCustomCollectionObject[i]);
}

myCustomCollectionObject.Sort(mycustomerComparer);

【讨论】:

  • 集合实现了ICollection,但没有实现IList,所以可能不支持索引。
  • 是的 - 好点。如果是这种情况 - 那么您可能无法对原始列表执行任何操作。
【解决方案2】:

刚好知道myCustomCollectionObject 不是List<T>,因此完全重写。


方法一:

在你的类中有一个Sort 方法

List<T> backingStructure; //assuming this is what you have.

public void Sort(IComparer<T> comparer)
{
    backingStructure = backingStructure.Where(obj => obj.isValid).ToList();
    backingStructure.Sort(comparer);
}

并在内部支持结构上调用Sort。我认为它必须是List&lt;T&gt;Array 两者都有Sort。我已将过滤逻辑添加到您的内部 Sort 方法。

方法2:

如果您不希望这样,即您希望您的过滤逻辑在类外部,那么有一种方法可以从IEnumerable&lt;T&gt; 重新填充您的支持结构。喜欢:

List<T> backingStructure; //assuming this is what you have.

//return type chosen to make method name meaningful, up to you to have void
public UndoRedoObservableCollection<T> From(IEnumerable<T> list)
{
    backingStructure.Clear();
    foreach(var item in list)
        //populate and return;
}

这样称呼

myCustomCollectionObject = myCustomCollectionObject.From
                           (
                               myCustomCollectionObject.Where(obj => obj.isValid)
                                                       .OrderBy(x => x.Key)
                           );

但您需要一个键来指定排序。

方法 3(最好的):

有一个RemoveInvalid 方法

List<T> backingStructure; //assuming this is what you have.

public void RemoveInvalid()
{
    //you can go for non-Linq (for loop) removal approach as well.
    backingStructure = backingStructure.Where(obj => obj.isValid).ToList();
}

public void Sort(IComparer<T> comparer)
{
    backingStructure.Sort(comparer);
}

叫它:

myCustomCollectionObject.RemoveInvalid();    
myCustomCollectionObject.Sort(mycustomerComparer);

【讨论】:

  • 你没有理解我的问题,这不是我想要的
  • @YogeshJoshi 对此感到抱歉。但是我能从 中得到更多信息吗?那么,有没有什么方法或解决方法可以在问题中实现第一次过滤然后对原始集合进行排序?请用一些示例/示例更新您的问题。但最重要的是,我现在很想知道您的具体要求是什么,因为我想不出另一种可能性:)
  • @svick 对我太苛刻了,不是吗?我将不得不通过整个 cmets 来挑选它。不过我会更新我的代码。
  • @nawfal 在问题的第一句话中提到:“我有一个自定义集合类”。
  • @svick 确实,谢谢和道歉。快速跳转到代码块并找到 SortToList 等,随后的所有内容看起来问题是 他无法在原始列表中排序而不是强调自定义收集东西:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-26
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 2015-09-18
相关资源
最近更新 更多