根据键对字典列表进行排序

本文关键字:排序 列表 字典 | 更新日期: 2023-09-27 18:10:16

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

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);  

我想根据name, agegender对学生列表进行排序,我正在尝试这样做:

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

如果我尝试agegender,它返回一个错误,关键是没有找到,因为std2没有agestd3没有gender

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

根据键对字典列表进行排序

最好创建一个这样的类:

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);

这种安排将相同的数据存储在多个字典中。然而,它要清晰易懂得多。

如果您希望按并非在所有字典中都存在的键进行排序,则需要返回默认值,例如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(...),它返回一个bool值,描述键是否在字典中找到并返回其值。

您可以通过提供一个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类型,而不是使用键值对的通用集合。