ratty
ratty

Reputation: 13444

how to break the loop if condition satisfies in linq?

I have list of ints consisting of

{1,2,3,1,2,1,5,1,2,1,1} 

I like retrieve all 1 located before 5 . I need skip all other items after 5 .The End list will be

{1,1,1}

How can i do this using linq?

Upvotes: 2

Views: 3438

Answers (2)

ShinNoNoir
ShinNoNoir

Reputation: 2283

Example showing the differences in laziness between Andrew Hare's solution and Saeed's solution.

class Program
{
    public static IEnumerable<int> TestData()
    {
        while (true)
            yield return 5;
    }

    public static IEnumerable<int> AndrewHare(IEnumerable<int> xs)
    {
        return xs.TakeWhile(i => i != 5)
                 .Where(j => j == 1);
    }

    public static IEnumerable<int> Saeed(IEnumerable<int> xs)
    {
        bool find5 = false;
        return xs.Where(p => p == 1 && !(find5 = (p == 5) ? true : find5));
    }

    static void Main(string[] args)
    {
        Stopwatch watch = new Stopwatch();

        watch.Restart();
        for (int i = 0; i < 1000000; i++)
        {
            foreach (var x in AndrewHare(TestData())) ;
        }
        watch.Stop();
        Console.WriteLine(watch.ElapsedMilliseconds);

        watch.Restart();
        for (int i = 0; i < 1000000; i++)
        {
            foreach (var x in Saeed(TestData())) ;
        }
        watch.Stop();
        Console.WriteLine(watch.ElapsedMilliseconds);

        Console.ReadKey();
    }
}

Upvotes: 2

Andrew Hare
Andrew Hare

Reputation: 351586

Try this:

using System.Linq;

class Program
{
    static void Main()
    {
        var list 
            = new[] { 1, 2, 3, 1, 2, 1, 5, 1, 2, 1, 1 };

        var filteredList 
            = list.TakeWhile(i => i != 5)
                    .Where(j => j == 1);
    }
}

The TakeWhile method yields all elements from the original sequence up until an element fails the predicate. So in this case we are yielding all the numbers from list until we reach one that equals 5.

Once we have done this we can simply filter down the resulting sequence to just the 1's using Where.

Upvotes: 15

Related Questions