Is a takewhile() checked every iteration using something like yeild, or does it just grab a set of elements all at once?

一个人想着一个人 提交于 2019-12-13 22:22:00

问题


for instance, let's say I want to do something like this:

bool foo(List<strings> stringList, int counter)//assume this list has, like, 10 elements, and counter=3, idk
{
    bool found= false;
    for(int i=0; i<stringlist.Count && !found; i++)
    {
        if(stringlist[i].length < 2 || counter >=6)
            found=true;
        counter++;
    }
    return found
}

Now, Is that equivelent to this:

bool foo(List<strings> stringList, int counter)//assume this list has, like, 10 elements, and counter=3, idk
{
    bool found= false;
    foreach(string s in stringlist.Takewhile(x=> (!found)))
    {
        if(s.length < 2 || counter >=6)
            found=true;
        counter++;
    }
    return found
}

Does this second example behave like the first, or does it always skip the whole loop? As a follow up, if I still want to use a foreach, do I really have to use a break to get around this? Also, sorry if I did something dumb in these examples, I am trying to simplify a version of a path-finding algo I am writing and this was the simplest example I could think of to ask this question...


回答1:


As the documentation of Microsoft here :

The TakeWhile(IEnumerable, Func) method tests each element of source by using predicate and yields the element if the result is true. Enumeration stops when the predicate function returns false for an element or when source contains no more elements.

and this is the decompiled TakeWhile() method :

public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
  if (source == null)
    throw Error.ArgumentNull(nameof (source));
  if (predicate == null)
    throw Error.ArgumentNull(nameof (predicate));
  return Enumerable.TakeWhileIterator<TSource>(source, predicate);
}

private static IEnumerable<TSource> TakeWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
  foreach (TSource source1 in source)
  {
    if (predicate(source1))
      yield return source1;
    else
      break;
  }
}

as you can see, yes the TakeWhile() method loops through all the elements doing the check and it's internal loop is irrelevant to your outer loop.



来源:https://stackoverflow.com/questions/52350696/is-a-takewhile-checked-every-iteration-using-something-like-yeild-or-does-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!