比较对象和返回列表

时间:2012-10-03 16:07:13

标签: c# c#-4.0

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

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的列表,我希望通过自定义排序过程按名称对它们进行排序,因为这涉及检查数据是否包含LastName(在这种情况下使用{{进行排序) 1}})或只是LastName(在这种情况下,我将打破字符串并在第二个术语上排序,如果有一个,或者只有整个字符串,如果只有一个单词。)

我不确定两件事:

  1. 我应该使用FirstLastName还是IComparer
  2. 一旦确定了排序的顺序(我可以这样做),我该怎么做才能使方法的输出是一个表示IComparable的整数列表。

4 个答案:

答案 0 :(得分: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();

答案 1 :(得分: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();

答案 2 :(得分: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();
}

答案 3 :(得分:1)

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

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

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

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