我有一个集合,最初是从这样的API返回的XML:
<table>
<row id="1">
<field id="date">2017-01-02</field>
<field id="salary">125000</field>
</row>
<row id="2">
<field id="date">2016-01-02</field>
<field id="salary">130000</field>
</row>
</table>
将XML反序列化为典型的POCO:
public class Table
{
public Row[] Rows { get;set; }
}
public class Row
{
public Field[] Fields { get;set; }
}
public class Field
{
public string Id { get;set; }
public string Value { get;set; }
}
API没有对返回行的顺序做出任何承诺,我想要检索具有最新日期值的行。如果日期是Row
对象上的实际属性,那么我可以使用https://stackoverflow.com/a/27686805/319980中显示的技术,(使用Min
LINQ运算符对Table.Rows
集合进行排序。 Date
属性)但这似乎不是一个选项,因为日期是子集合的值。
假设date
字段始终存在,可以在纯LINQ中完成吗?
答案 0 :(得分:4)
您可以做的是按Rows
订购date
,然后选择第一行。要按date
排序,您应该解析字符串:
var result = table.Rows.OrderByDescending(r => DateTime.ParseExact(
r.Fields.FirstOrDefault(f => f.Id == "date")?.Value ?? DateTime.MinValue.ToString("yyyy-MM-dd"),
"yyyy-MM-dd",
CultureInfo.InvariantCulture)).FirstOrDefault();
更强大的版本可以使用TryParse
作为日期而不仅仅是解析,并且在失败的情况下返回DateTime.MinValue
因此不选择行
答案 1 :(得分:2)
您可以使用OrderByDescending
和First
运算符来获取结果。假设date
字段始终存在并且它是有效日期,您可以这样写:
table.Rows
.OrderByDescending(r => DateTime.ParseExact(r.Fields.First(f => f.Id == "date").Value, "yyyy-MM-dd", CultureInfo.InvariantCulture))
.First();
如果您可以添加morelinq
包,则可以使用MaxBy
运算符:
table.Rows
.MaxBy(r => DateTime.ParseExact(r.Fields.First(f => f.Id == "date").Value, "yyyy-MM-dd", CultureInfo.InvariantCulture));