简体   繁体   English

检查IEnumerable是否具有少于一定数量的项目而不会导致任何不必要的评估?

[英]Check if an IEnumerable has less than a certain number of items without causing any unnecessary evaluation?

Sometimes I expect a certain range of items and need to do some validation to ensure that I am within that range. 有时我希望有一定范围的项目,需要进行一些验证以确保我在该范围内。 The most obvious way to do this is to just compare the number of items in the collection with the range. 最明显的方法是将集合中的项目数与范围进行比较。

public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max)
{
    return enumerable.Count() <= max;
}

Although, my understanding is that the linq Count() method will evaluate the entire enumerable before returning a result. 虽然,我的理解是linq Count()方法将在返回结果之前评估整个可枚举。 Ideally I would only cause evaluation on the minimal number of items to get my result. 理想情况下,我只会对最小数量的项目进行评估以获得我的结果。

What would be the best way to ensure that an enumerable has less than a certain number of items without causing any unnecessary evaluation? 在不引起任何不必要评估的情况下,确保可枚举项目少于一定数量的最佳方法是什么?

Don't use Count() , as you already know, the entire collection would have to be traversed in general. 不要使用Count() ,正如您所知,整个集合必须遍历。

You can do this instead: 你可以这样做:

public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max)
{
    return !enumerable.Skip(max).Any();
}

Note you will still have to enumerate over the first max items in the collection, that's unavoidable unless you try to make some assumptions about the underlying collection. 请注意,您仍然必须枚举集合中的第一个max项目,除非您尝试对基础集合做出一些假设,否则这是不可避免的。


To really optimize this further, you can check if the underlying type is an ICollection<> or ICollection in order to access the Count property. 要进一步优化这一点,您可以检查基础类型是否为ICollection<>ICollection以访问Count属性。 That way you don't have to enumerate over the items at all. 这样您就不必枚举项目了。 Otherwise fallback on enumerating the items. 否则在枚举项目时回退。

public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max)
{
    var asCollection = enumerable as System.Collections.ICollection;
    if (asCollection != null) return asCollection.Count <= max;
    var asGenericCollection = enumerable as ICollection<T>;
    if (asGenericCollection != null) return asGenericCollection.Count <= max;
    return !enumerable.Skip(max).Any();
}

Of course this isn't exactly free as you're doing additional checks, but it beats having to enumerate over the collection if at all possible, particularly if max is large. 当然,这并不是完全免费的,因为你正在进行额外的检查,但是如果可能的话,它必须在集合上进行枚举,特别是如果max很大。

There are several different ways to do this. 有几种不同的方法可以做到这一点。 Perhaps the simplest is: 也许最简单的是:

public static bool IsWithinRange<T>(this IEnumerable<T> enumerable, int max)
{
    return enumerable.Take(max+1).Count() <= max;
}

你可以将Count()Take()结合起来。

return enumerable.Take(max + 1).Count() <= max;

检查 IEnumerable<object> 里面有任何值而没有得到 IndexOutOfRangeException<div id="text_translate"><p> 我有一个IEnumerable&lt;object&gt; 。 我想检查IEnumerable&lt;object&gt;里面是否有任何值。</p><p> 我的方法如下所示:</p><pre> private static JObject TransformExcelDatasource(Stream originalDatasource) { // Read Excel Data var excelReader = new ExcelReader(originalDatasource); var sheetReader = excelReader[0]; //Check if row has any values var row = sheetReader.Row(100); var rowHasValues = row.Any(); if (rowHasValues) { //do stuff } }</pre><p> 我尝试获取只有 3 行的 excel 表的第 100 行。 我知道,这只是一个 POC。</p><p> 行var rowHasValues = row.Any(); throws System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'</p><p> 这是变量IEnumerable&lt;object&gt; row的样子: <a href="https://i.stack.imgur.com/quYVJ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/quYVJ.png" alt="在此处输入图像描述"></a></p><p> 我尝试了这个问题的答案( <a href="https://stackoverflow.com/questions/52575358/ienumerable-indexoutofrangeexception" rel="nofollow noreferrer">第一个</a>, <a href="https://stackoverflow.com/questions/27277534/index-out-of-bounds-in-linq-enumerable" rel="nofollow noreferrer">第二个</a>),但对我没有任何帮助。</p><p> <strong>如何检查IEnumerable&lt;object&gt; row是否有任何值而不获得 IndexOutOfRangeException?</strong></p><p> <strong>更新</strong></p><p>这是抛出的 IndexOutOfRangeException <a href="https://i.stack.imgur.com/SJN18.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/SJN18.png" alt="![在此处输入图像描述"></a></p><p> row.Current也不是一个选项,因为它IEnumerable&lt;object&gt;不包含它。 <a href="https://i.stack.imgur.com/GshWk.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/GshWk.png" alt="在此处输入图像描述"></a></p><p> 完整的堆栈跟踪:</p><pre> at LightWeightExcelReader.SheetReader.get_Item(String cellAddress) at LightWeightExcelReader.SheetReader.&lt;get_Item&gt;b__8_1(String x) at System.Linq.Utilities.&lt;&gt;c__DisplayClass2_0`3.&lt;CombineSelectors&gt;b__0(TSource x) at System.Linq.Enumerable.SelectListIterator`2.MoveNext() at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source) at NR.DataAdapter.Core.Services.TransformDatasourceService.TransformExcelDatasource(Stream originalDatasource) in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.Core\Services\TransformDatasourceService.cs:line 35 at NR.DataAdapter.Core.Services.TransformDatasourceService.TransformDatasource(IDatasource interpretedDatasource) in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.Core\Services\TransformDatasourceService.cs:line 19 at NR.DataAdapter.Core.DataAdapter.AdaptDatasources() in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.Core\DataAdapter.cs:line 24 at NR.DataAdapter.UI.Controllers.HomeController.Dashboard() in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.UI\Controllers\HomeController.cs:line 24 at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync() at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State&amp; next, Scope&amp; scope, Object&amp; state, Boolean&amp; isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()</pre></div></object> - Check if IEnumerable<object> has any values inside without getting IndexOutOfRangeException

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 检查 IEnumerable 是否有任何行而不枚举整个列表 - Check if IEnumerable has ANY rows without enumerating over the entire list 检查 IEnumerable<object> 里面有任何值而没有得到 IndexOutOfRangeException<div id="text_translate"><p> 我有一个IEnumerable&lt;object&gt; 。 我想检查IEnumerable&lt;object&gt;里面是否有任何值。</p><p> 我的方法如下所示:</p><pre> private static JObject TransformExcelDatasource(Stream originalDatasource) { // Read Excel Data var excelReader = new ExcelReader(originalDatasource); var sheetReader = excelReader[0]; //Check if row has any values var row = sheetReader.Row(100); var rowHasValues = row.Any(); if (rowHasValues) { //do stuff } }</pre><p> 我尝试获取只有 3 行的 excel 表的第 100 行。 我知道,这只是一个 POC。</p><p> 行var rowHasValues = row.Any(); throws System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'</p><p> 这是变量IEnumerable&lt;object&gt; row的样子: <a href="https://i.stack.imgur.com/quYVJ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/quYVJ.png" alt="在此处输入图像描述"></a></p><p> 我尝试了这个问题的答案( <a href="https://stackoverflow.com/questions/52575358/ienumerable-indexoutofrangeexception" rel="nofollow noreferrer">第一个</a>, <a href="https://stackoverflow.com/questions/27277534/index-out-of-bounds-in-linq-enumerable" rel="nofollow noreferrer">第二个</a>),但对我没有任何帮助。</p><p> <strong>如何检查IEnumerable&lt;object&gt; row是否有任何值而不获得 IndexOutOfRangeException?</strong></p><p> <strong>更新</strong></p><p>这是抛出的 IndexOutOfRangeException <a href="https://i.stack.imgur.com/SJN18.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/SJN18.png" alt="![在此处输入图像描述"></a></p><p> row.Current也不是一个选项,因为它IEnumerable&lt;object&gt;不包含它。 <a href="https://i.stack.imgur.com/GshWk.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/GshWk.png" alt="在此处输入图像描述"></a></p><p> 完整的堆栈跟踪:</p><pre> at LightWeightExcelReader.SheetReader.get_Item(String cellAddress) at LightWeightExcelReader.SheetReader.&lt;get_Item&gt;b__8_1(String x) at System.Linq.Utilities.&lt;&gt;c__DisplayClass2_0`3.&lt;CombineSelectors&gt;b__0(TSource x) at System.Linq.Enumerable.SelectListIterator`2.MoveNext() at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source) at NR.DataAdapter.Core.Services.TransformDatasourceService.TransformExcelDatasource(Stream originalDatasource) in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.Core\Services\TransformDatasourceService.cs:line 35 at NR.DataAdapter.Core.Services.TransformDatasourceService.TransformDatasource(IDatasource interpretedDatasource) in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.Core\Services\TransformDatasourceService.cs:line 19 at NR.DataAdapter.Core.DataAdapter.AdaptDatasources() in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.Core\DataAdapter.cs:line 24 at NR.DataAdapter.UI.Controllers.HomeController.Dashboard() in C:\Dev\src\ipa-dataadapter\NR.DataAdapter.UI\Controllers\HomeController.cs:line 24 at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync() at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State&amp; next, Scope&amp; scope, Object&amp; state, Boolean&amp; isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()</pre></div></object> - Check if IEnumerable<object> has any values inside without getting IndexOutOfRangeException 简单的C#:如何检查字符串输入既是有效数字又小于特定数字? - Simple C#: How to check String input is both a valid number AND less than a certain number? 使用LINQ检查IEnumerable <T?>的所有项是否具有相同的值 - Check that all items of IEnumerable<T?> has the same value using LINQ 如何检查IEnumerable <DataRow> 返回null或有任何行? - How to check IEnumerable<DataRow> returns null or has any row? 检查是否等于任何元素 - check ienumerable for any elements 有没有比.Any()找到IEnumerable更快的方法 <T> 有任何数据吗? - Is there any faster way than .Any() to find if IEnumerable<T> has any data? IE无数评估 - IEnumerable evaluation 如何检查最大数是否大于 1 - How to check if the maximum number has more than 1 子项目中无数个项目中正在运行的项目数 - Running number of items in subgroups within ienumerable of items
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM