用于在列表中查找一项并验证列表不包含其他项的 LINQ 查询
本文关键字:列表 验证 包含 查询 LINQ 其他 查找 用于 一项 | 更新日期: 2023-09-27 18:37:13
到目前为止,我已经想出了这个:
list.Any(s => s.EnumIdValue == Close) && !list.Any(s => s.EnumIdValue == Reset || s.EnumIdValue == Cancel);
EnumIdValue 包含几个不同的可能值,如关闭、重置、取消、SomeOtherState 等。永远不应该有重复,但它仍然是可能的。
这完全符合我的需求。但是会有更好(更短)的方法来编写此查询吗?
你的原件很好。另一个可行的变体是这样的:
var newQuery =
list.Any(s => s.EnumIdValue == EnumIdValue.Close) &&
list.All(s => s.EnumIdValue != EnumIdValue.Reset &&
s.EnumIdValue != EnumIdValue.Cancel);
英语:列表是否至少有一个Close
,列表中的每个项目是否不Reset
也不Cancel
?
顺便说一下,有时格式化代码在可读性方面有很大的不同。
答案是:没有更好的方法来写它。
如果您尝试将其写入一个 lambda,则可以将s
视为列表中的单个项目。如果该项目是Close
,它当然不会是其他东西,因此在同一 lambda 中检查它是没有用的。如果要检查列表是否不包含其他值,则必须使用另一个表达式执行此操作。
您可以使用 HashSet 来测试集合是否至少包含每个EnumIdValue
中的 1 个:
var enumIds = list.Select(s => s.EnumIdValue).ToHashSet();
return enumIds.Contains(Close) && !(enumIds.Contains(Cancel) || enumIds.Contains(Reset));
// or
return enumIds
.Intersect(new[] { Cancel, Reset, Close })
.SequenceEqual(new [] { Close });
// or (throws exception)
enumIds.IntersectWith(new[] { Cancel, Reset, Close })
return enumIds.Single() == Close;
如果您需要根据enumIds
是否包含Close
进行不同类型的检查,这将很有用。
怎么样
var items = list.Select(s => s.EnumIdValue == Close)
if(items.Count==1)
{
//todo
}
这是一个相当可读的替代方案:
var opts = new [] { Close, Reset, Cancel };
var desired = new [] { Close };
return list
.Select(s => s.EnumIdValue)
.Distinct()
.Where(opts.Contains)
.SequenceEqual(desired);