根据特定条件将列表项高效移动到列表末尾的方法

3

拥有一个List<Office>,其中Office是一个类,我需要按国家(国家是Office类的属性)对其条目进行排序。

一些办公室没有设置国家,因此将显示在列表顶部。在这种情况下,我必须将它们放在列表底部,因为被认为是“不那么相关”。

switch (sortOptions.SortField)

...  

case OfficeSortField.Country:

var noCountryList = officesList.Where(a => string.IsNullOrEmpty(a.CountryText)).ToList();
officesList.RemoveAll(a => string.IsNullOrEmpty(a.CountryText));

officesList= sortOptions.SortOrder == SortOrder.Ascending
                                      ? officesList.OrderBy(o => o.CountryText).ToList()
                                      : officesList.OrderByDescending(o => o.CountryText).ToList();

officesList.AddRange(noCountryAssoList);
break;

在性能方面,是否有更好的方式进行?

哪种语言?大多数都有一个“sort”函数,您可以使用它来按自定义标准进行排序。 - laurent
所有类似且良好的答案均可。在我的情况下,仅在非常特定的情况下需要列表末尾的移动(这只是Telerick Grid的许多排序可能性中的一个)。我将发布我的代码以确保完整性,尽管不如建议的代码高效或优雅。 - Francesco
7个回答

2
最好的方法是使用自定义函数进行排序。
您可以将其作为委托来完成:
list.Sort((first, second) =>
      {
         // Your code to compare first and second items
         // return 0 if equal, -1 or +1 for other cases
      });

您可以一次性完成所有流程,不需要提取没有国家的办公室。

2
当然有。试试这个:

当然有。试试这个:

List<Office> list = new List<Office>(...);

list.Sort((x, y) => x.Country == null ? (y.Country == null ? 0 : -1) :
    (y.Country == null ? 1 : Comparer<Office>.Default.Compare(x, y))

或者,你最好实现比较器(如果你打算重复使用排序功能)。
class OfficeComparer : IComparer<Office>
{
    public int Compare(Office a, Office b)
    {
        return a.Country == null ? (b.Country == null ? 0 : -1) :
            (b.Country == null ? 1 : Comparer<Office>.Default.Compare(a, b))
    }
}

然后你可以使用它:
List<Office> list = new List<Office>(...);
list.Sort(new OfficeComparer());

2

最好的方法是实现一个比较器

class OfficeComparer:IComparer<Office>
{
        int IComparer.Compare(Office a, Office b)
        {
               if ( a.Office.Country != null && b.Office.Country != null) 
                       return a.Office.Country.CompareTo(b.Office.Country);
               if ( a.Office.Country == null && b.Office.Country != null) return -1;
               if ( a.Office.Country != null && b.Office.Country == null) return 1;  
               return 0; // if both have no country, return equal or whatever other criteria comparaison

        }
}

在您的比较器中,只需给没有国家的办公室一个低优先级,然后调用排序方法即可。
List<Office> lst = FillList();

lst.sort(new OfficeComparer());

2
这些操作的性能差异非常微小,不值得担心。如果您还没有这样做,建议使用Linq来执行逻辑以按您想要的方式进行排序,这样就不必进行任何删除/插入操作。
然后,如果您想进一步提高性能,请考虑使用Plinq将逻辑分布在多个核心上。

在我的情况下,可能不会有太多的元素需要使用Plinq。然而,这是一个未来考虑的好点子+1! - Francesco

0

0

这是最简单和性能最有效的方法,我检索了所有物理书籍,在其中我想将类别“其他”推到列表的末尾。

List<Books> controlGroupDetails = controlDetails.Where(s => s.Title == "Physics").ToList();
var otherPhysics = controlDetails.Where(s => s.Title == "Physics" && s.Name == "Other").SingleOrDefault();
controlGroupDetails.Remove(otherPhysics);
controlGroupDetails.Insert(controlGroupDetails.Count(), otherPhysics);

-1
在Java中,您可以实现Comparable<T>接口,然后通过调用java.util.Collections.sort(List<T> list)对列表进行排序。
详见:
public class Office implements Comparable<Office> {
  private String country;
  public int compareTo(Office off) {
    if (this.country == null)
      return -1;
    else if (off.country == null)
      return 1;
    else
      return this.country.compareTo(off.country);
  }
}

排序列表:

java.util.Collections.sort(yourOfficeList);

好的,忽略我的帖子。但是希望在C#中有类似的东西。 - Roy Ling
当然了。Java 就像 C# 一样 :) - AgentFire
你只比较了第一个和第二个,实际上应该双向比较。 - AgentFire
@AgentFire:在Java中不需要这样做,这与C#中的代码是一样的,可以参考lcfseth的答案。 - Roy Ling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接