按字段值排序字典值,该值是给定字段的对象列表

时间:2015-06-17 10:55:33

标签: c# linq sorting dictionary

我有一个SortedDictionary,其值是一个对象列表。我想按对象的给定属性对每个键的值(列表)进行排序。在当前情况下,我需要先按对象的姓氏排序列表,然后按名字排序。我试过LINQ,它很快就变得很讨厌而没有产生结果。

编辑:

我有以下结构:

    public class Person
    {
        private string firstName;
        private string lastName;

        ...
    }

我需要按键排序的字典。但是,我需要先按Person的lastName,然后按firstName。

对每个List进行排序
var dict = new SortedDictionary<string, List<Person>>();

我没有提供排序代码,因为我无法让它工作。这就是我寻求帮助的原因。

3 个答案:

答案 0 :(得分:2)

您可以使用List.Sort,LINQ在这种情况下不起作用,因为您无法修改字典(fe Add或使用Value属性)枚举:

foreach(var kv in yourSortedDictionary)
{
    kv.Value.Sort((p1, p2) => {
        int diff = p1.LastName.CompareTo(p2.LastName);
        if(diff != 0) return diff;
        return p1.FirstName.CompareTo(p2.FirstName);
    });
}

即使首先添加已排序的列表也会更好。

但正如我在评论中已经提到的那样,如果列表不能包含重复项,则可以使用SortedSet<Person>代替List<Person>。 .NET仍缺少允许重复但已排序的单一值集合类型。

答案 1 :(得分:1)

通常我会创建一个新的IEnumerable而不是尝试改变现有的集合。 (这是Linq的方法):

IEnumerable<Tuple<string, List<Person>> dict = dict
 .Select(x => Tuple.Create(
    x => x.Key, 
    x => x.Value.OrderBy(x => x.LastName).ThenBy(x => x.FirstName)));

你也可以将它放入字典中,但可能不需要它。您要么对它进行排序(按照List的位置),要么按键访问(在这种情况下您不需要对其进行排序,在这种情况下使用ToDictionary)。

当你在最后对它进行排序时(或者在查询中添加另一个OrderBy),你可能甚至不需要排序的字典作为源代码。

答案 2 :(得分:0)

我有一个类似的挑战,并通过在foreach(..)语句中将包含对象的字典排序为动态值来解决它。

以下是我如何做到这一点的示例../给出原始方案...

public class Person
  {
    private string firstName;
    private string lastName;  
    ...
  }

...
Dictionary<string, Person> dictPersons = new Dictionary<string, Person>();
// statements to populate the dictionary with keys and a Person objects.
....
foreach(var personEntry in dictPersons.ORderBy(p => p.Value.lastName).ThenBy(p => p.Value.firstName)
  {
  ...
  // When you use the firtName or lastName properties,just refer to it as:
  Console.WriteLine("LastName: {0}  FirstName: {1}", personEntry.Value.lastName, personEntry.Value.firstName);
  ...
}

希望这有助于将来需要它的人......