【问题标题】:How to Sort a List of Objects by dictionary value?如何按字典值对对象列表进行排序?
【发布时间】:2011-07-17 01:20:20
【问题描述】:

如何按 Person 中选择的字典值对其进行排序?

示例:“人”按“汽车”值降序排列的顺序列表。

这些花哨的 lambda/linq 方程之一有可能吗?

public class People 
{
    List<Person> Persons { get; set; }
}

public class Person
{
    public Dictionary<string, string> cars { get; set; } 
    public Dictionary<string, string> houses { get; set; } 
    public Dictionary<string, string> banks { get; set; }
}

................

People people = new People();

people.Persons = new List<Person> 
{
    new Person 
    {
        cars = new Dictionary<string, string> { { "volvo", "340050" }, { "bmw", "50545000" } }, 
        houses = new Dictionary<string, string> { { "mansion", "100040000" },{ "cardboard box", "112" } },
        banks = new Dictionary<string, string> { { "swiss", "12500330000" }, { "camen", "12000000" } }
    }, 
    new Person 
    {
        cars = new Dictionary<string, string> { { "volvo", "34023200" }, { "bmw", "5003300" } }, 
        houses = new Dictionary<string, string> { { "mansion", "1000330000" },{ "cardboard box", "277" } },
        banks = new Dictionary<string, string> { { "swiss", "12500044000" }, { "camen", "12000000" } }
    }, 
    new Person 
    {
        cars = new Dictionary<string, string> { { "volvo", "3554000" }, { "bmw", "50023200" } }, 
        houses = new Dictionary<string, string> { { "mansion", "1006600000" },{ "cardboard box", "244" } },
        banks = new Dictionary<string, string> { { "swiss", "125000544000" }, { "camen", "12000777000" } }
    }
};

编辑/示例结果:

结果将是基于每个人的字典中包含的值的新列表或重新排序的列表

人 -> 汽车 -> { "volvo", "34023200" }
人 -> 汽车 -> {“沃尔沃”、“3554000”}
人 -> 汽车 -> {“沃尔沃”,“340050”}

新的或重新排序的 List 看起来就像这样:

people.Persons = new List<Person> 
{
    new Person 
    {
        cars = new Dictionary<string, string> { { "volvo", "34023200" }, { "bmw", "5003300" } }, 
        houses = new Dictionary<string, string> { { "mansion", "1000330000" },{ "cardboard box", "277" } },
        banks = new Dictionary<string, string> { { "swiss", "12500044000" }, { "camen", "12000000" } }
    },
    new Person 
    {
        cars = new Dictionary<string, string> { { "volvo", "3554000" }, { "bmw", "50023200" } }, 
        houses = new Dictionary<string, string> { { "mansion", "1006600000" },{ "cardboard box", "244" } },
        banks = new Dictionary<string, string> { { "swiss", "125000544000" }, { "camen", "12000777000" } }
    },
    new Person 
    {
        cars = new Dictionary<string, string> { { "volvo", "340050" }, { "bmw", "50545000" } }, 
        houses = new Dictionary<string, string> { { "mansion", "100040000" },{ "cardboard box", "112" } },
        banks = new Dictionary<string, string> { { "swiss", "12500330000" }, { "camen", "12000000" } }
    }
};

【问题讨论】:

  • 汽车是什么意思?车名?
  • 每个人都包含汽车及其价值的字典。我怎样才能对每个人进行排序?
  • 凭什么?你有字典、键或值吗?
  • 对不起,我现在将添加一些示例输出。

标签: c# linq sorting lambda


【解决方案1】:

这是一个绝妙的技巧;基本上,可以将 Dictionary 视为 KeyValuePair 对象的列表。

Dictionary<int, string> myDictionary = new Dictionary<int, string>();
foreach(var item in myDictionary)
// item is a KeyValuePair<int, string>, enumerated in order of their insertion into the dictionary

现在它在列表中,很容易通过 LINQ 进行排序:

Dictionary<int, string> sample = new Dictionary<int, string>
{
   { 1, "Sample" },
   { 2, "Another Sample" }
};

var orderedList = sample.OrderBy(x => x.Value).ToList();

当然,更大的问题是为什么您需要对字典进行排序和排序 - 这并不是真正与字典概念分组的操作(它更多的是通过指定键快速访问特定元素) .你写的问题描述看起来很奇怪;您可以为特定的人订购汽车,但您是否试图从按价值订购的每个人那里找到每辆汽车?

这也很容易做到:

List<PersonCarDetails> allStuff = new List<PersonCarDetails>();

foreach(var person in persons)
   allStuff.AddRange(person.Cars.Select(x => new PersonCarDetails { PersonId = person.Id, CarName = x.Key, CarId = x.Value }).ToList());

 // allStuff now contains a list of PersonCarDetails, and then you can order that:

 var orderedList = allStuff.OrderBy(x => x.CarId).ToList();

【讨论】:

  • 我很难解释我的问题。我不是要订购字典。我的意思是按每个 Person 中的字典值对 List 进行排序。
  • 你会如何选择字典的哪个元素来排序?例如,您说比较人 1 和人 2。您将人 1 的汽车字典的哪个组件与人 2 的汽车字典的哪个组件进行比较?字典不是有序的数据集合。
  • 我可以像 foreach (Person p in people.Persons) { string carValue = p.car["volvo"]; } 这样访问列表。字典不是有序集合,但列表是。我只想按每个 Person 中的字典值对所有 Person 进行排序。
  • 我之前在问题区域中添加了一个示例输出。
  • 如果您想按所需的字典元素对人员列表进行排序,您可以这样做。 var people = people.Persons.OrderBy(x =&gt; x.Cars.First(kv =&gt; kv.Key == "volvo").Value)。请注意,如果该人的汽车字典中没有值为“volvo”的键,则此代码将破坏块。
【解决方案2】:

如果您的意思是按个人拥有的汽车数量排序

var result = Person.OrderByDescending(x => x.cars.Count);

如果您的意思是按此人拥有的第一个(按名称排序)汽车名称进行排序

var result = Person.OrderByDescending(x => x.cars.Keys.OrderBy(y => y.Key).FirstOrDefault());

如果您的意思是按此人拥有的第一个(按编号排序)车号排序

var result = Person.OrderByDescending(x => x.cars.Keys.OrderBy(y => y.value).FirstOrDefault());

一个示例输出可以很好地阐明您实际想要排序的内容,因为汽车是一个列表,而不仅仅是一个元素。


根据您提供的示例,这可能适合您:

var result = Person.OrderByDescending(x => x.cars.Values.FirstOrDefault());

【讨论】:

  • 按要求添加了示例输出。现在也在看你的例子。谢谢。
猜你喜欢
  • 2010-11-15
  • 2011-02-22
  • 2010-09-09
相关资源
最近更新 更多