2

我有一个如下所示的类定义:

public class MyObjectModel
{
   public int ObjectID { get; set; }

   //for when the user's data is split in 2 fields
   public string FirstName { get; set; }
   public string LastName { get; set; }

   //for when the user's data is all in one field
   public string FirstLastName { get; set; }
}

我有一个列表,MyObjectModel我想使用自定义排序过程按名称对它们进行排序,因为这涉及检查数据是否包含 a LastName(在本例中使用 排序LastName)或仅FirstLastName(在本例中我将破坏字符串并在第二个词上排序,如果有的话,或者如果只有一个词,就对整个字符串进行排序。)

我不确定两件事:

  1. 我应该使用IComparerorIComparable吗?
  2. 一旦它确定了排序的顺序(我可以这样做),我该如何做到这一点,以便该方法的输出是一个表示ObjectID.
4

4 回答 4

3

使用 Linq:

  List<MyObjectModel> objects = new List<MyObjectModel>();
  List<int> ids = objects.OrderBy(o => FunctionWhichReturnsNameForSort(o)).Select(o => o.ObjectID).ToList();

FunctionWhichReturnsNameForSort可以在另一个类、扩展或成员中实现。

// should be in a static helper class
public static string NameForSort(this MyObjectModel obj)
{
  if (!string.IsNullOrEmpty(obj.LastName)) return obj.LastName;

  return obj.FirstLastName.Split(... // your splitting logic goes here
}

var ids = objects.OrderBy(o => o.NameForSort()).Select(o => o.ObjectID).ToList();
于 2012-10-03T16:11:07.460 回答
2

当你真的需要这个奇怪的双重解决方案时,你会更频繁地遇到这个和类似的问题。作为更通用的解决方案,考虑将名称的业务逻辑放在一些只读属性中:

//for when the user's data is split in 2 fields
public string FirstName { get; set; }
public string LastName { get; set; }

//for when the user's data is all in one field
public string FirstLastName { get; set; }

public string FullName
{
   get { ... }  // pick from LastName, FirstName, FirstLastName 
}

public string SortName
{
   get { ... }  // pick from LastName, FirstLastName 
}

一旦它确定了排序的顺序(我可以这样做),我该如何做到这一点,以便该方法的输出是一个表示 ObjectID 的整数列表

result = MyObjectList
          .OrderBy(m => m.SortName)   // sort on SortName
          .Select(m => m.ObjectID)    // select the Id
          .ToList();
于 2012-10-03T16:11:59.160 回答
1

如果这种排序特定于一个用例,则可以使用 LINQ 来实现:

var sortedIds = models.OrderBy(SecondName).Select(m => m.ObjectId).ToList();

private static string SecondName(MyObjectModel model)
{
  if (!string.IsNullOrWhitespace(model.LastName)) return model.LastName;
  return model.FirstLastName.Split(' ').Last();
}
于 2012-10-03T16:11:29.003 回答
1

虽然您可以使用 LINQ,但正如其他人所建议的那样,这将涉及创建一个全新的列表,而不是改变现有列表。这可能会或可能不会更可取。如果您想对列表本身进行排序,这也很容易:

List<string> list = new List<string>(){"a","b","c"};

list.Sort((a,b)=> a.CompareTo(b));

只需获取您的列表,调用Sort并传入一个 lambda,该 lambda 接受两个项目并返回一个整数,指示哪个更大。在您的情况下,只需调用一些方法ab获取一个字符串,然后在这两个字符串上使用CompareTo或。string.Compare

于 2012-10-03T16:15:54.413 回答