LINQ之Skip,SkipWhile

返回LINQ大全首頁

Skip()

如果我不需要此數組的第一個元素,那麼有沒有辦法只刪除第一個元素並得到其餘的元素?
Skip()就是爲了解決這種情況而存在的。
如果您從頭開始指定不需要的元素數目,則將返回該數目之後的元素序列。
MSDN
public static IEnumerable<TSource> Skip<TSource>( this IEnumerable<TSource> source, int count );

代碼示例:

public static class Program
{
    static void Main( string[] args )
    {
        int[]       numbers = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        string[]    texts   = new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

        // 跳過開始的3個
        IEnumerable<int>    skippedNumbers  = numbers.Skip( 3 );
        // 跳過開始的4個
        IEnumerable<string> skippedTexts    = texts.Skip( 4 );

        System.Console.WriteLine( "skippedNumbers:{0}", skippedNumbers.Text() );
        System.Console.WriteLine( "skippedTexts:{0}",   skippedTexts.Text() );

        System.Console.ReadKey();
    }

    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 

skippedNumbers:[3], [4], [5], [6], [7], [8], [9],
skippedTexts:[Thu], [Fri], [Sat],

如果將大於總數的數字或負數傳遞給此參數,它也會正常工作。
具體效果看下面案例。

示例代碼:

public static class Program
{
    static void Main( string[] args )
    {
        int[] numbers = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        string[]    texts   = new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

        // 超過總數
        IEnumerable<int>    skippedNumbers  = numbers.Skip( 100 );
        // 跳過負數
        IEnumerable<string> skippedTexts    = texts.Skip( -5 );

        System.Console.WriteLine( "skippedNumbers:{0}", skippedNumbers.Text() );
        System.Console.WriteLine( "skippedTexts:{0}",   skippedTexts.Text() );

        System.Console.ReadKey();
    }

    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 

skippedNumbers:
skippedTexts:[Sun], [Mon], [Tue], [Wed], [Thu], [Fri], [Sat],

由此我們可以發現,參數爲負數時會獲取所有元素,參數大於元素總數獲取不到元素。

SkipWhile()

Skip()可以指定跳過的數目。
但是您可能需要指定特定的跳過條件,而不是元素數。在這種情況下就可以使用SkipWhile()
您可以在參數中設置跳過的條件
MSDN
public static IEnumerable<TSource> SkipWhile<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate );
它將跳過滿足條件的元素
在下面的示例中,使用lambda表達式描述了條件語句。

代碼示例:

public static class Program
{
    static void Main( string[] args )
    {
        int[]       numbers = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        string[]    texts   = new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

        // 小與7的
        IEnumerable<int>    skippedNumbers  = numbers.SkipWhile( value => value < 7 );
        // 刪除尾字母爲n的
        IEnumerable<string> skippedTexts    = texts.SkipWhile( value => value.EndsWith( "n" ) );

        System.Console.WriteLine( "skippedNumbers:{0}", skippedNumbers.Text() );
        System.Console.WriteLine( "skippedTexts:{0}",   skippedTexts.Text() );

        System.Console.ReadKey();
    }

    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 

skippedNumbers:[7], [8], [9],
skippedTexts:[Tue], [Wed], [Thu], [Fri], [Sat],

當您使用SkipWhile()指定要跳過的條件時,不僅可以獲取每個元素的信息,還可以獲取每個元素的索引值。

public static IEnumerable<TSource> SkipWhile<TSource>( this IEnumerable<TSource> source, Func<TSource, int, bool> predicate );

在以下示例中,index索引號作爲參數在lambda表達式條件語句中傳遞。

代碼示例:

public static class Program
{
    static void Main( string[] args )
    {
        int[]       numbers = new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
        string[]    texts   = new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

        // value值 * 索引值小於20
        IEnumerable<int>    skippedNumbers  = numbers.SkipWhile( ( value, index ) => value * index < 20 );
        // value的長度大於索引值
        IEnumerable<string> skippedTexts    = texts.SkipWhile( ( value, index ) => value.Length > index );

        System.Console.WriteLine( "skippedNumbers:{0}", skippedNumbers.Text() );
        System.Console.WriteLine( "skippedTexts:{0}",   skippedTexts.Text() );

        System.Console.ReadKey();
    }

    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 

skippedNumbers:[5], [4], [3], [2], [1], [0],
skippedTexts:[Wed], [Thu], [Fri], [Sat],

SkipWhile()和Where()的區別

SkipWhile()和LINQ函數中的Where()類似。
MSDN
public static IEnumerable<TSource> Where<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate );

Where()是與條件具有相同元素的函數。
讓我們將此Where()與SkipWhile()進行比較。

在下面的示例中,描述了省略低於指定數值的元素的條件。

代碼示例:

public static class Program
{
    static void Main( string[] args )
    {
        int[]   numbers = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        // 值小於5
        IEnumerable<int>    skippedNumbers  = numbers.SkipWhile( value => value < 5 );
        // 值大於等於5
        IEnumerable<int>    whereNumbers    = numbers.Where( value => value >= 5 );

        System.Console.WriteLine( "skippedNumbers:{0}", skippedNumbers.Text() );
        System.Console.WriteLine( "whereNumbers  :{0}",   whereNumbers.Text() );

        System.Console.ReadKey();
    }

    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 

skippedNumbers:[5], [6], [7], [8], [9],
whereNumbers :[5], [6], [7], [8], [9],

得到了相同的結果。
前面我們使用的是有組織的數據,其中作爲數據的值按升序排列。
現在,讓我們打亂此數據序列,然後再次進行驗證。

代碼示例:

public static class Program
{
    static void Main( string[] args )
    {
        int[]   numbers = new int[] { 0, 3, 6, 1, 4, 5, 8, 7, 2, 9 };
        // 值小於5
        IEnumerable<int>    skippedNumbers  = numbers.SkipWhile( value => value < 5 );
        // 值大於等於5
        IEnumerable<int>    whereNumbers    = numbers.Where( value => value >= 5 );

        System.Console.WriteLine( "skippedNumbers:{0}", skippedNumbers.Text() );
        System.Console.WriteLine( "whereNumbers  :{0}",   whereNumbers.Text() );

        System.Console.ReadKey();
    }

    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 

skippedNumbers:[6], [1], [4], [5], [8], [7], [2], [9],
whereNumbers :[6], [5], [8], [7], [9],

結果變更。
Where(),移除所有符合條件的元素,並返回其他元素。
SkipWhile(),從頭開始算,遇到符合條件的的元素就移除,遇到不符合條件的直接結束,無論後續有沒有符合條件的元素。

因此,Where()的結果是返回所有不小於5的所有元素。
SkipWhile()的結果是移除從頭開始小於5的元素。如遇到不滿足條件的則直接停止

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章