C# Skip vs SkipWhile
When the need is to skip N count of items in a list we can rely on LINQ extension Skip(int count)
BasicallySkip
extension performs a loop and continue until intteration count greater then the given count. For example;
Let’s say we have list of strings and we want to skip first two,
What we do is (without using LINQ),
static void Main(string[] args)
{
List<string> items = new List<string>() { "Berkay", "Yaylacı", "Developer", "com" };
int count = 2;
List<string> result = new List<string>();
for (int i = count; i < items.Count; i++)
{
result.Add(items[i]);
}
Console.WriteLine(String.Join(",", result.ToArray()));
Console.ReadKey();
}
We have just gave our count as starting index, and basically we have skipped items with given count
We can use Skip()
to shorten this,
static void Main(string[] args)
{
List<string> items = new List<string>() { "Berkay", "Yaylacı", "Developer", "com" };
List<string> result = items.Skip(2).ToList();
Console.WriteLine(String.Join(",", result.ToArray()));
Console.ReadKey();
}
We have an obvious winner!
Let’s increase number of items in the list (this time I need to use integer array to produce much more items) lets say 100.000 then 1.000.000
static void Main(string[] args)
{
List<int> items = Enumerable.Repeat(0, 1000000).ToList();
int count = 500;
List<int> result = new List<int>();
var stopWatch = Stopwatch.StartNew();
for (int i = count; i < items.Count; i++)
{
result.Add(items[i]);
}
Console.WriteLine("TraditionalPerformance:" + stopWatch.Elapsed.TotalMilliseconds);
stopWatch = Stopwatch.StartNew();
List<int> result2 = items.Skip(count).ToList();
Console.WriteLine("SkipPerformance:" + stopWatch.Elapsed.TotalMilliseconds);
Console.ReadKey();
}
First 100.000 items result,
1.000.000 items result,
Over 1 Million items;
Skip()
performance is much more better then Traditional way.
Why for loop lost performance? Here is the performance result,
1.000.000 -> Allocation has been done at the beginning took much more time but getCount and getItem performances are increased
100.000 -> getCount and getItem performance are three times slower then 1 million allocated list.
Okay, we have strayed from our topic. Let’s continue with SkipWhile()
,
They both have the same purpose. Skip some items depends on a condition. Skip()
has one condition which is an integer count parameter.
But!SkipWhile()
can take predicate as a parameter.
First let’s try with traditional way,
static void Main(string[] args)
{
List<string> items = new List<string>() { "Berkay", "Yaylacı", "Developer", "com" };
List<string> result = new List<string>();
bool isFound = false;
foreach(var item in items)
{
if (!item.Contains("c") && !isFound)
{
isFound = true;
continue;
}
result.Add(item);
}
Console.WriteLine(string.Join(",", result));
}
With SkipWhile()
,
static void Main(string[] args)
{
List<string> items = new List<string>() { "Berkay", "Yaylacı", "Developer", "com" };
List<string> result = items.SkipWhile(x=> !x.Contains("c")).ToList();
Console.WriteLine(String.Join(",", result.ToArray()));
Console.ReadKey();
}
Here, we gave condition to our SkipWhile()
extension. What we have wrote here is:
SkipWhile(x=> !x.Contains(“c”)) => “Skip until a word contains C letter”.
1- It has skipped "Berkay" because there is no "C".
2- Then it came to “Yaylacı”.
3- SkipWhile method has ended because “Yaylacı” has C letter.