简体   繁体   中英

Linq TakeWhile in loop, giving only first result

I'm using a takewhile statement in a loop and its only giving results on the first iteration of the loop. All the subsequent iterations are not producing results, even though I would expect them to.

For example the code below. The first iterations will give string a="blah1blah2blah3". On the second iteration I would expect a="blah2blah3", but the takewhile is giving nothing a="", its getting no elements.

In the real world scenario this is a big loop of logic, so I can't afford to do the takewhile outside of the loop. I've tried to use a combination of count() and take(), but count() gives all the elements that qualify, not the count of items that qualify until the condition is false.

Any help would be useful, thanks.

Code:

public void blah()
{
    List<testclass> someStrings = new List<testclass>() 
    { new testclass() { name = "blah1", testNum = 1 },
      new testclass() { name = "blah2", testNum = 2 },
      new testclass() { name = "blah3", testNum = 3 },
      new testclass() { name = "none4", testNum = 4 },
      new testclass() { name = "blah5", testNum = 5 },
      new testclass() { name = "blah6", testNum = 6 },
      new testclass() { name = "none7", testNum = 7 } 
    };

    foreach (testclass tc in someStrings)
    {
       string a = string.Join("", someStrings.TakeWhile(i => i.name.Contains("blah") 
                           && i.testNum >= tc.testNum).Select(g => g.name.ToString()));
    }
}

I am not sure what you are trying to achieve from this but the problem with your code is, when you loop executes for second time ie for testNum as 2 your query looks like this:-

string a = someStrings.Where(i => i.name.Contains("blah")
                                    && i.testNum >= 2).Select(g => g.name.ToString());

So, Obviously the first condition itself will fail ie i.testNum >= 2 for first element which contains 1 and you will get nothing or String.Empty as output.

As far as what I have understood, you can achieve what you want by adding SkipWhile before as suggested by @CodeDennis to skip previous records like this:-

string a = string.Join("", someStrings.SkipWhile(i => i.testNum < tc.testNum)
            .TakeWhile(i => i.name.Contains("blah") && i.testNum >= tc.testNum)
            .Select(g => g.name.ToString()));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM