C# C LINQ查询列表
我有一个列表,其中字典如下: 我必须使用字典,因为我从API检索不同的对象,并且指定每个对象是不可行的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
{
[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,你不会得到一个包含任何元素的序列错误。