无需嵌套的复杂Linq过滤无数if/foreach
Complicated Linq filtering without nesting countless if/foreach
我有一个包含给定字段的集合:
class InternalConditionModel
{
public string ProductId { get; set; }
public double Value { get; set; }
public DateTime DateFrom { get; set; }
public DateTime DateThru { get; set; }
public bool IsSSoldOnlyOnDisplay { get; set; }
}
并且必须根据给定条件对其进行过滤:
如果集合中有多个项目具有相同的 ProductId,我会检查 IsSoldOnlyOnDisplay 并选择结果为 true 的项目。但是,如果有多个为真,我会选择价值最大的一项。
通过 GroupBy(ProductId) 执行此操作,然后执行多个 ifs/foreaches 非常简单。但我想知道是否有可能用 linq 将其简化为更“漂亮”的东西。
应该这样做:
var result = items.GroupBy(x => x.ProductId).Select(x => x.OrderByDescending(y => y.Value).FirstOrDefault(y => x.Count(z => z.IsSSoldOnlyOnDisplay) == 1 ? y.IsSSoldOnlyOnDisplay : true));
首先我们按产品编号分组。然后我们按值降序对每个组进行排序(具有最大值的项目将排在第一位)。在这个排序组中,我们取第一个项目。如果该组只有一个项目 IsSSoldOnlyOnDisplay
为真,则 FirstOrDefault
的条件为 IsSSoldOnlyOnDisplay
,否则条件为 true
,即只取第一个项目团体。由于排序较早,因此它会是具有最高值的那个。
但是你自己想想这段代码是否真的比一些循环和if更好。我不建议将所有内容强制放入单个 LINQ 查询中。
Online-demo: https://dotnetfiddle.net/SzuL0p
我有一个包含给定字段的集合:
class InternalConditionModel
{
public string ProductId { get; set; }
public double Value { get; set; }
public DateTime DateFrom { get; set; }
public DateTime DateThru { get; set; }
public bool IsSSoldOnlyOnDisplay { get; set; }
}
并且必须根据给定条件对其进行过滤:
如果集合中有多个项目具有相同的 ProductId,我会检查 IsSoldOnlyOnDisplay 并选择结果为 true 的项目。但是,如果有多个为真,我会选择价值最大的一项。
通过 GroupBy(ProductId) 执行此操作,然后执行多个 ifs/foreaches 非常简单。但我想知道是否有可能用 linq 将其简化为更“漂亮”的东西。
应该这样做:
var result = items.GroupBy(x => x.ProductId).Select(x => x.OrderByDescending(y => y.Value).FirstOrDefault(y => x.Count(z => z.IsSSoldOnlyOnDisplay) == 1 ? y.IsSSoldOnlyOnDisplay : true));
首先我们按产品编号分组。然后我们按值降序对每个组进行排序(具有最大值的项目将排在第一位)。在这个排序组中,我们取第一个项目。如果该组只有一个项目 IsSSoldOnlyOnDisplay
为真,则 FirstOrDefault
的条件为 IsSSoldOnlyOnDisplay
,否则条件为 true
,即只取第一个项目团体。由于排序较早,因此它会是具有最高值的那个。
但是你自己想想这段代码是否真的比一些循环和if更好。我不建议将所有内容强制放入单个 LINQ 查询中。
Online-demo: https://dotnetfiddle.net/SzuL0p