Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ First/FirstOrDefault是否迭代整个可枚举项?_C#_Algorithm_Linq_Big O - Fatal编程技术网

C# LINQ First/FirstOrDefault是否迭代整个可枚举项?

C# LINQ First/FirstOrDefault是否迭代整个可枚举项?,c#,algorithm,linq,big-o,C#,Algorithm,Linq,Big O,上下文: 我有一个类型为IEnumerable的变量numbers 我想检查数字是否按升序排列 算法 因此,我得到了第一个元素,将其存储在prev中,并希望对照接下来的数字进行检查 // numbers can contain "10, 20, 60, 50" IEnumerable<int> numbers = TraverseInOrder(root); int prev = numbers.FirstOrDefault(); foreach (var curr in numbe

上下文:

我有一个类型为IEnumerable的变量
numbers

我想检查数字是否按升序排列

算法

因此,我得到了第一个元素,将其存储在
prev
中,并希望对照接下来的数字进行检查

// numbers can contain "10, 20, 60, 50"
IEnumerable<int> numbers = TraverseInOrder(root);
int prev = numbers.FirstOrDefault();
foreach (var curr in numbers.Skip(1))
{
    if (curr < prev) return false;
    prev = curr;
}
return true;
我是否将
数字枚举两次O(2N)?意思是迭代整个列表?
-或-
还是O(N)吗?(O(1)对于
FirstOrDefault
+O(N)对于
Skip(1)

这有点微妙

Enumerable.FirstOrDefault
不会枚举整个序列,因为这样做没有意义。这是:

publicstatictsourcefirstOrdefault(此IEnumerable源代码){
if(source==null)抛出错误.ArgumentNull(“source”);
IList list=源作为IList;
如果(列表!=null){
如果(list.Count>0)返回列表[0];
}
否则{
使用(IEnumerator e=source.GetEnumerator()){
如果(e.MoveNext())返回e.Current;
}
}
返回默认值(TSource);
}
如果基础序列是
IList
,则会得到优化版本,否则将启动枚举

现在假设您的
IEnumerable
实际上是一个实体框架
IQueryable
,它表示一个数据库查询。这意味着您的代码仍将执行两次查询

最好避免根据经验多次枚举
IEnumerable
序列。如果您知道枚举序列很便宜,那么应该使用更具描述性的类型,如
ICollection
IReadOnlyCollection

FirstOrDefault()
不会迭代整个集合

只要做:

var moreNumbers = numbers.ToList();
// ...stuff with the list. 

我会巧妙地改变你的技巧,这样你就不需要知道了(尽管其他答案都是针对你特别要求的):

IEnumerable numbers=traverseInoder(根);
int prev=0;
bool first=true;
foreach(数值形式的var curr)
{
如果(!first&&curr

现在您知道了(即使没有阅读文档!)这段代码只会对可枚举项迭代一次。

或者最好看看源代码@Sung you's correct,上面有很多不好的问题,因此不应该问,因为阅读文档可以轻松地回答这些问题。这并不意味着可以通过阅读文档来提出一些简单的问题。因此,这不是一个提问的地方,因为您不必费心在文档中查找答案,也不必运行自己的代码来查看它的功能。或者只需
int prev=int.MinValue
感谢这里的伟大提示@Damien_the_unsiver我也阅读了
source.GetEnumerator()的源代码“将启动枚举”
FirstOrDefault
将只到达第一个元素。感谢您的回答@Sung yes,但在数据库查询的示例中,您将只检索第一行,但仍将执行查询以到达该行。
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
    IList<TSource> list = source as IList<TSource>;
    if (list != null) {
        if (list.Count > 0) return list[0];
    }
    else {
        using (IEnumerator<TSource> e = source.GetEnumerator()) {
            if (e.MoveNext()) return e.Current;
        }
    }
    return default(TSource);
}
var moreNumbers = numbers.ToList();
// ...stuff with the list. 
IEnumerable<int> numbers = TraverseInOrder(root);
int prev = 0;
bool first = true;
foreach (var curr in numbers)
{
    if (!first && curr < prev) return false;
    prev = curr;
    first = false;
}
return true;