【问题标题】:Sorting a list of dictionaries based on a key根据键对字典列表进行排序
【发布时间】:2015-11-23 22:33:50
【问题描述】:

我有一个包含学生数据的字典列表 有点像

List<Dictionary<string, object>> students = new List<Dictionary<string, object>>();
Dictionary<string, object> std1 = new Dictionary<string, object>();
std1["name"] = "sai";
std1["age"] = 22;
std1["gender"] = "male";
students.Add(std1);

Dictionary<string, object> std2 = new Dictionary<string, object>();
std2["name"] = "Julia";
std2["gender"] = "female";
students.Add(std2);

Dictionary<string, object> std3 = new Dictionary<string, object>();
std3 ["name"] = "sunny";
std3 ["age"] = 23;
students.Add(std3);  

我想根据nameagegender 对学生列表进行排序,我正在尝试这样的事情:

var ordered = students.OrderBy(x => x["name"]);

如果我尝试使用agegender,则会返回找不到密钥的错误,因为std2 没有agestd3 没有gender

我需要所有记录,即使它不包含排序键的值,任何解决此问题的方法,提前致谢。

【问题讨论】:

  • 使用字典而不是类是否有特定原因?

标签: c# linq list sorting dictionary


【解决方案1】:

最好像这样创建一个类:

public class YourClass
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }
}

然后:

List<YourClass> students = new List<YourClass>();
YourClass std1 = new YourClass();
std1.Name = "sai";
std1.Age = 22;
std1.Gender = "male";
students.Add(std1);

yourClass std2 = new yourClass();
std2.Name = "Julia";
std2.Gender = "female";
students.Add(std2);

yourClass std3 = new yourClass();
std3.Name = "sunny";
std3.Age = 23;
students.Add(std3);

var ordered = students.OrderBy(x => x.Name);

这种排列方式存储了您在多个字典中的相同数据。但是,它更加清晰易懂。

【讨论】:

  • 谢谢 :),它帮助了我
  • @satishkumarV 这绝对是您应该采用的解决方案,除非您必须使用字典。
  • 是的,我同意你的观点,但问题是字典可能包含任何数据和任何没有键,有时它可能包含学生数据,其他时间的员工和地址,我可以'不要创建 100 或 1000 的类,无论如何,如果键列表是恒定的并且已修复,此解决方案可能很棒:) 并感谢您的建议。
  • 如果您还必须以某种方式表示员工数据,这是继承的经典案例。非常不鼓励使用字典来解决这类问题。
【解决方案2】:

如果您想按并非所有字典中都存在的键进行排序,则需要返回一个默认值,例如 0。

var ordered = students.OrderBy(dict =>
{
    string name;
    if (!dict.TryGetValue("name", out name))
        return "";
    return name;
});

使用条件三元运算符的较短版本:

var ordered = students.OrderBy(dict =>
{
    string name;
    return dict.TryGetValue("name", out name) ? name : 0;
});

我使用Dictionary.TryGetValue(...),它返回一个布尔值,描述是否在字典中找到键并返回它的值。

【讨论】:

  • Awesome :) +1 解释 TryGetValue
【解决方案3】:

您可以通过提供GetOptional 方法来解决此问题,该方法在字典没有特定键的情况下返回一些默认对象:

V GetOptional<K,V>(IDictionary<K,V> d, K key, V absent) {
    V res;
    return d.TryGetValue(key, out res) ? res : absent;
}

现在你可以这样排序:

var byName = students.OrderBy(x => GetOptional<string,object>(x, "name", "----"));
var byAge = students.OrderBy(x => GetOptional<string,object>(x, "age", "10000"));

注意:使用这样的字典可以为您提供灵活性,但会降低清晰度。通常最好定义一个特殊的 Student 类型,而不是使用键值对的通用集合。

【讨论】:

  • 谢谢 :),它帮助了我
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多