按字典键值对在列表中进行排序。

huangapple go评论73阅读模式
英文:

OrderBy in List on the basis of Dictionary Key-Value

问题

我有以下的列表:

List<Student> list = 
[
  {
    "id": 1,
    "name": "学生1",
    "OtherInformation": {
      "hobby": "音乐",
      "Score": 50
    }
  },
  {
    "id": 2,
    "name": "学生2",
    "OtherInformation": {
      "hobby": "高尔夫",
      "Score": 70
    }
  },
  {
    "id": 3,
    "name": "学生3",
    "OtherInformation": {
      "hobby": "射箭",
      "Score": 30
    }
  }
]

Other Information 是一个字典,我需要使用字典中的动态值来对整个列表进行排序。

var sortKey = "id";
var propertyInfo = typeof(Student).GetProperty(sortKey);
list = list.OrderBy(x => propertyInfo.GetValue(x, null)).ToList();

我无法对字典中的键值(如 Score)使用上述解决方案。

Student.cs

public class Student
{
    public string Id { get; set; }
    public string Name { get; set; }
    public IDictionary<string, object> OtherInfomration { get; set; }
}

需要帮助。

英文:

I have the following List:

List&lt;Student&gt; list = 
[
  {
    &quot;id&quot;: 1,
    &quot;name&quot;: &quot;Student 1&quot;,
    &quot;OtherInformation&quot;: {
      &quot;hobby&quot;: &quot;Music&quot;,
      &quot;Score&quot;: 50
    }
  },
  {
    &quot;id&quot;: 2,
    &quot;name&quot;: &quot;Student 2&quot;,
    &quot;OtherInformation&quot;: {
      &quot;hobby&quot;: &quot;Golf&quot;,
      &quot;Score&quot;: 70
    }
  },
  {
    &quot;id&quot;: 3,
    &quot;name&quot;: &quot;Student 3&quot;,
    &quot;OtherInformation&quot;: {
      &quot;hobby&quot;: &quot;Archery&quot;,
      &quot;Score&quot;: 30
    }
  }
]

Other Information is a Dictionary and I need to OrderBy the complete list using the dictionary Value which will be dynamic i.e. stored in some variable.

var sortKey = &quot;id&quot;;
var propertyInfo = typeof(Student).GetProperty(sortKey);
list = list.OrderBy(x =&gt; propertyInfo.GetValue(x, null)).ToList();

I'm not able to do the above solution for Dictionary Key-Values such as Score

Student.cs

 public class Student
{
 public string Id {get;set;}
 public string Name {get;set;}
 public IDictionary&lt;string, object&gt; OtherInfomration{get;set;}
}

Help needed.

答案1

得分: 2

我认为您想要执行以下操作:

var sortKey = "OtherInformation";
var propertyInfo = typeof(Student).GetProperty(sortKey);
list = list.OrderBy(x => ((IDictionary<string, object>)propertyInfo.GetValue(x, null))["Score"]).ToList();

不过,目前并不太清楚您为什么要使用反射。您可以轻松地这样做:

list = list.OrderBy(x => x.OtherInformation["Score"]).ToList();
英文:

I think you want to do this:

var sortKey = &quot;OtherInformation&quot;;
var propertyInfo = typeof(Student).GetProperty(sortKey);
list = list.OrderBy(x =&gt; ((IDictionary&lt;string, object&gt;)propertyInfo.GetValue(x, null))[&quot;Score&quot;]).ToList();

Its not entirely clear why you're using reflection however. You could easily just do this:

list = list.OrderBy(x =&gt; x.OtherInformation[&quot;Score&quot;]).ToList();

答案2

得分: 0

这是使用这些数据制作的一个迷你控制台应用程序:

class Program
{
    static void Main(string[] args)
    {
        List<Student> list = new List<Student>()
        {
            new Student() { Id = 1, Name = "Student 1", OtherInformation = new Dictionary<string, string>()
                {
                    { "hobby", "Music" },
                    { "Score",  "50" }
                }
            },
            new Student() { Id = 2, Name = "Student 2", OtherInformation = new Dictionary<string, string>()
                {
                    { "hobby", "Golf" },
                    { "Score",  "70" }
                }
            },
            new Student() { Id = 3, Name = "Student 3", OtherInformation = new Dictionary<string, string>()
                {
                    { "hobby", "Archery" },
                    { "Score",  "30" }
                }
            }
        };

        Console.WriteLine(list.OrderBy(x => x.OtherInformation["Score"]).FirstOrDefault().Name);
        Console.Read();
    }
}

结果是预期的学生3,因为他的分数最低。

编辑:

在这里,您可以使用预定义的排序语句:

public class OrderByStatement
{
    private string propertyName;

    public OrderByStatement(string propertyName)
    {
        this.propertyName = propertyName;
    }

    public Expression<Func<Student, object>> GetOrderBy()
    {
        switch (this.propertyName)
        {
            case "id": return s => s.Id;
            case "name": return s => s.Name;
            case "score": return s => s.OtherInformation["Score"];
            case "hobby": return s => s.OtherInformation["hobby"];
            default: return s => s.Id;
        }
    }
}

// 调用示例:
Console.WriteLine(list.OrderBy(new OrderByStatement("id").GetOrderBy().Compile()).FirstOrDefault().Name);
Console.WriteLine(list.OrderBy(new OrderByStatement("score").GetOrderBy().Compile()).FirstOrDefault().Name);

您可以通过定义继承来更改代码,而不是使用 new OrderByStatement("[propertyName]"),您可以使用 new IdOrderBy()

希望这回答了您的问题。

英文:

I made a mini console application using this data:

 class Program
 {
     static void Main(string[] args)
     {
         List&lt;Student&gt; list = new List&lt;Student&gt;()
            {
             new Student() { Id = 1, Name = &quot;Student 1&quot;, OtherInformation = new Dictionary&lt;string, string&gt;()
                                         {
                                             { &quot;hobby&quot;, &quot;Music&quot; },
                                             { &quot;Score&quot;,  &quot;50&quot; }
                                         }
                                     },
             new Student() { Id = 2, Name = &quot;Student 2&quot;, OtherInformation = new Dictionary&lt;string, string&gt;()
                                         {
                                             { &quot;hobby&quot;, &quot;Golf&quot; },
                                             { &quot;Score&quot;,  &quot;70&quot; }
                                         }
                                     },
             new Student() { Id = 3, Name = &quot;Student 3&quot;, OtherInformation = new Dictionary&lt;string, string&gt;()
                                         {
                                             { &quot;hobby&quot;, &quot;Archery&quot; },
                                             { &quot;Score&quot;,  &quot;30&quot; }
                                         }
                                     }
         };

         Console.WriteLine(list.OrderBy(x =&gt; x.OtherInformation[&quot;Score&quot;]).FirstOrDefault().Name);
         Console.Read();
      }
 }

The result was Student 3 as wanted because he has the lowest score.

EDIT:

Here you can use a pre-defined order statments:

public class OrderByStatment
{
    private string propertyName;

    public OrderByStatment(string propertyName)
    {
        this.propertyName = propertyName;
    }

    public Expression&lt;Func&lt;Student, object&gt;&gt; GetOrderBy()
    {
        switch (this.propertyName)
        {
            case &quot;id&quot;: return s =&gt; s.Id;
            case &quot;name&quot;: return s =&gt; s.Name;
            case &quot;score&quot;: return s =&gt; s.OtherInformation[&quot;Score&quot;];
            case &quot;hobby&quot;: return s =&gt; s.OtherInformation[&quot;hobby&quot;];
            default: return s =&gt; s.Id;
        }
    }
}

calling it will be then:

Console.WriteLine(list.OrderBy(new OrderByStatment(&quot;id&quot;).GetOrderBy().Compile()).FirstOrDefault().Name);
Console.WriteLine(list.OrderBy(new OrderByStatment(&quot;score&quot;).GetOrderBy().Compile()).FirstOrDefault().Name);

You can absolutely make the code better by defining inheritance. Instead of new OrderByStatment("[propertyName]") you can use new IdOrderBy()

Hope that answers your question

答案3

得分: 0

你可以这样做:

var sorted = list.OrderBy(x => Convert.ToInt32(x.OtherInformation["Score"]));

Convert.ToInt32 有点不稳定,因为它可能引发异常。

英文:

You can do this:

var sorted = list.OrderBy(x =&gt; Convert.ToInt32(x.OtherInformation[&quot;Score&quot;]));

Convert.ToInt32 is a bit dodgy as it can throw an exception.

huangapple
  • 本文由 发表于 2020年1月3日 19:56:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/59578202.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定