C#LINQ查询列表<dicitonary <string,object =“”>&gt; </dicitonary <string,>

时间:2014-05-01 14:49:23

标签: c# linq list dictionary

我有一个List<Dictionary<string, object>> Dictionary<string, object>就像:

我必须使用Dictionary<string, object>,因为我从API检索不同的对象并指定每个对象是不可行的。

{
    [id, 12345],
    [action, SUBMIT],
    [comment, blah blah]
    ...
},
{
    [id, 98765],
    [action, DECLINE],
    [comment, yak yak]
    ...
}

&#39; ID&#39;总是一个整数。

如何使用LINQ从列表中查询最大ID?在这种情况下,返回id = 98765。

3 个答案:

答案 0 :(得分:3)

让我们将问题分解为组成部分:

  1. 我需要将每个字典中的ID条目提取到一个集合中。
  2. 我需要将值转换为整数。
  3. 我需要获得该组的最大值。
  4. 我们如何通过键访问字典条目的值? myDictionary["key"]。这很脆弱,因为它假定字典总是有一个带有该键的条目。如果没有,则会抛出异常。

    我们如何使用LINQ从现有序列生成新的对象序列? Select()。描述源中每个对象的输出对象。

    我们使用int.Parse从字符串中获取int。这很脆弱,通常是禁止,因为如果该字符串值不是一个完整的整数,它将抛出异常。但是为了简单起见,我们可以假设我们可以假设所有字符串都是整数,就像你说的那样。

    最后一位是最简单的 - Max()适用于任何可比项目序列:

    var maxId = theList.Select(dict => int.Parse(dict["id"].ToString())).Max();
    

    现在一个更安全的版本会确保做两件事:

    1. 检查字典是否 条目,如果没有,请决定如何处理。
    2. 检查实际的条目值是否可以转换为整数,如果没有,则决定如何处理。
    3. 这是一种只跳过不符合这两个要求的条目的方法。如果没有条目通过,DefaultIfEmpty(-1)生成一个带有单个条目的序列,-1。

      int tryParse;
      var onlyEntriesWithIdThatAreIntegers = theList.Where(
          dict => dict.ContainsKey("id")
              && dict["id"] != null
              && int.TryParse(dict["id"].ToString(), out tryParse))
          .DefaultIfEmpty(-1);
      
      var max = onlyEntriesWithIdThatAreIntegers.Select(
          dict => int.Parse(dict["id"].ToString())).Max();
      

答案 1 :(得分:1)

这可能就是你要找的东西:

    var result = youList.Select(p=>int.Parse(p["id"])).Max();

答案 2 :(得分:0)

就个人而言,我同意格兰特。您应该使用对象而不是字典来表示对象。

var values = new List<Dictionary<string, object>>();
... populate the list ...

int maxIdValue = values.Where(v => v.Keys.Contains("id")).Select(v => (int) v["id"]).Max();

您应该检查以确保字典包含ID属性,否则您将获得异常。此外,您应该使用不区分大小写的词典来处理您正在做的事情。比较速度更快,而您(“id,Id,ID”)对于您的目的来说完全相同。此外,Int.Parse是缓慢的。如果对象是一个Int,只需要转换它,bo需要把它变成一个字符串,然后解析它以将它转换回它已经是的类型!但是,如果你必须使用int.Parse,因为值不能保证为int,那么请使用TryParse。否则,再一次,未处理的异常

编辑:

如果你想使用tryParse,这是一个例子:

        var intValues = values.Where(v => v.Keys.Contains("id")).Select(v =>
        {
            int val;
            if (int.TryParse(v["id"].ToString(), out val))
            {
                return val;
            }
            return int.MinValue;
        }).Where(v => v > int.MinValue);

        int? maxIdValue = null;
        if (intValues.Any())
            maxIdValue = intValues.Max();