2012-10-03 121 views
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的名单,我想,因为这涉及到检查,如果通过名称与自定义排序过程中对它们进行排序该数据包含LastName(在这种情况下使用LastName排序)或FirstLastName(在这种情况下,我将打破字符串并对第二项进行排序,如果有的话,或者只有一个字,如果只有一个字)

我不确定两件事:

  1. 应该使用IComparerIComparable
  2. 一旦它确定排序的顺序(我可以做到这一点),我该如何做到这一点,以便该方法的输出是代表ObjectID的整数列表。
+1

根据您使用的C#版本,您可以使用Linq对其进行排序。 –

+0

对于精度,我使用的是c#4. – frenchie

回答

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(); 
+0

FunctionWhichReturnsNameForSort函数应该返回什么?它应该根据比较逻辑返回-1,0,1吗? – frenchie

+0

它应该返回一个用于排序的名称。我会添加一个例子。 –

+0

好的,谢谢。我将把这与霍特曼的答案结合起来! – frenchie

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(); 
} 
+0

某些姓氏有多个部分(空格)。 –

+0

在名称字符串包含多个部分的情况下,我正在比较第二个字符串。 – frenchie

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(); 
+0

我喜欢这个想法:而不是在对象的属性上进行比较,而是对返回我正在排序的字符串的函数的输出进行比较。你是这个意思吗? – frenchie

+0

是的。排序一个特殊的属性,把它保存在你的班级里面。 –

+0

好的,谢谢你的主意! – frenchie

1

虽然你可以使用LINQ INTS的列表,如其他人所说,这将涉及创建一个全新的列表,而不是突变的现有列表。这可能会或可能不会更好。如果要排序,很容易够得列表本身:

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

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

只要看看你的列表,通话Sort,并传递一个lambda,它有两个项目,并返回一个整数,表示这是更大的。在你的情况下,只需在ab上调用一些方法来获得一个字符串,然后在这两个字符串上使用CompareTostring.Compare