Reputation: 13444
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
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
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