C# C LINQ查询列表

C# C LINQ查询列表,c#,linq,list,dictionary,C#,Linq,List,Dictionary,我有一个列表,其中字典如下: 我必须使用字典,因为我从API检索不同的对象,并且指定每个对象是不可行的 { [id, 12345], [action, SUBMIT], [comment, blah blah] ... }, { [id, 98765], [action, DECLINE], [comment, yak yak] ... } “id”始终是一个整数 如何使用LINQ从列表中查询最大id?在这种情况下,返回id=98

我有一个列表,其中字典如下:

我必须使用字典,因为我从API检索不同的对象,并且指定每个对象是不可行的

{
    [id, 12345],
    [action, SUBMIT],
    [comment, blah blah]
    ...
},
{
    [id, 98765],
    [action, DECLINE],
    [comment, yak yak]
    ...
}
“id”始终是一个整数


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

这可能就是您要查找的内容:

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

这可能就是您想要的:

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

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

我需要将每个字典中的ID条目提取到一个集合中。 我需要把这个值转换成一个整数。 我需要得到该集合的最大值。 我们如何通过字典项的键访问它的值?我的字典[钥匙]。这是脆弱的,因为它假设字典中总是有一个带有该键的条目。如果没有,它将抛出一个异常

如何使用LINQ从现有序列生成新的对象序列?选择描述源中每个对象的输出对象

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

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

var maxId = theList.Select(dict => int.Parse(dict["id"].ToString())).Max();
现在,更安全的版本将确保做两件事:

检查字典是否有id条目,如果没有,决定如何处理。 检查输入值是否可以转换为整数,如果不能,决定如何处理。 这里有一种方法可以跳过不符合这两个要求的条目。如果没有通过的条目,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();

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

我需要将每个字典中的ID条目提取到一个集合中。 我需要把这个值转换成一个整数。 我需要得到该集合的最大值。 我们如何通过字典项的键访问它的值?我的字典[钥匙]。这是脆弱的,因为它假设字典中总是有一个带有该键的条目。如果没有,它将抛出一个异常

如何使用LINQ从现有序列生成新的对象序列?选择描述源中每个对象的输出对象

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

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

var maxId = theList.Select(dict => int.Parse(dict["id"].ToString())).Max();
现在,更安全的版本将确保做两件事:

检查字典是否有id条目,如果没有,决定如何处理。 检查输入值是否可以转换为整数,如果不能,决定如何处理。 这里有一种方法可以跳过不符合这两个要求的条目。如果没有通过的条目,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();

我个人同意格兰特的观点。应该使用对象而不是字典来表示对象

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

我个人同意格兰特的观点。应该使用对象而不是字典来表示对象

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

你自己试过吗?有什么尝试吗?我使用过LINQ几次,但不熟悉如何查询字典项,在Google上找不到任何关于如何执行此操作的信息。我强烈建议将这些字典转换为实际对象,使用属性而不是键,使用这些属性的值而不是键对中的值。如果你真的必须这样做,那很好,但是如果你可以避免,而且你通常可以,你真的应该这样做。你自己试过这样做吗?有什么尝试吗?我使用过LINQ几次,但不熟悉如何查询字典项,在Google上找不到任何关于如何执行此操作的信息。我强烈建议将这些字典转换为实际对象,使用属性而不是键,使用这些属性的值而不是键对中的值。如果你真的必须这样做,那很好,但是如果你可以避免,而且你通常可以,你真的应该这样做。谢谢大家的回答。我只选择这一个作为正确答案,因为它分解了示例,解释查询的各个部分非常有用!。顺便说一句,我不得不使用dict[id].ToString,因为它是一个对象,以防其他人遇到这个答案。@BrianKE很高兴你发现它很有用。如果你想接受这个答案,点击左边投票按钮下的复选标记。我试图接受,但显然要等10分钟。你只需要等待,这是对你作为一个如此快速和优秀的老师的惩罚顺便说一句,我该怎么办
将“@Rex M”添加到注释中,就像您对@BrianKE所做的那样,这有什么作用?@BrianKE键入“@”和名称的前几个字母,它会弹出一个自动完成。但它必须是注释中的第一个字符。它所做的主要事情是确保你得到一个站点范围的警告,即有评论是针对你的。谢谢大家的回答。我只选择这一个作为正确答案,因为它分解了示例,解释查询的各个部分非常有用!。顺便说一句,我不得不使用dict[id].ToString,因为它是一个对象,以防其他人遇到这个答案。@BrianKE很高兴你发现它很有用。如果你想接受这个答案,点击左边投票按钮下的复选标记。我试图接受,但显然要等10分钟。你只需要等待,这是对你作为一个如此快速和优秀的老师的惩罚顺便说一句,我如何在评论中添加“@Rex M”,就像你对@BrianKE所做的那样,这有什么作用?@BrianKE键入“@”和名称的前几个字母,它会自动弹出一个完整的窗口。但它必须是注释中的第一个字符。它所做的主要事情是确保你得到一个站点范围的警告,即有评论是针对你的。我同意使用TryParse,但不知道如何在这种情况下应用它。TryParse返回bool,我不确定如何设置out值,以便LINQ查询可以访问它。有什么想法吗?谢谢,我没有意识到你可以做{}标注。我再次修改了它,以确保如果没有可解析的int,你不会得到一个不包含任何元素的序列错误。我同意使用TryParse,但不知道如何在这种情况下应用它。TryParse返回bool,我不确定如何设置out值,以便LINQ查询可以访问它。有什么想法吗?谢谢你,我没有意识到你可以做{}标注。我再次修改了它,以确保如果没有可解析的int,你不会得到一个包含任何元素的序列错误。