LINQ之Take, TakeWhile

返回LINQ大全首页

Take()

Take()可以获取序列的指定部分。具体使用请看下面案例。

MSDN
public static IEnumerable<TSource> Take<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>    takenNumbers    = numbers.Take( 3 );
        // 开始的4个
        IEnumerable<string> takenTexts      = texts.Take( 4 );

        System.Console.WriteLine( "takenNumbers:{0}", takenNumbers.Text() );
        System.Console.WriteLine( "takenTexts  :{0}", takenTexts.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;
    }
}

takenNumbers:[0], [1], [2],
takenTexts :[Sun], [Mon], [Tue], [Wed],

如果将大于元素总数的数字或负数传递给此参数,它也会正常工作。负数的话相当于0。

代码示例:

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>    takenNumbers    = numbers.Take( 100 );
        // 负数
        IEnumerable<string> takenTexts      = texts.Take( -5 );

        System.Console.WriteLine( "takenNumbers:{0}", takenNumbers.Text() );
        System.Console.WriteLine( "takenTexts  :{0}", takenTexts.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;
    }
}

takenNumbers:[0], [1], [2], [3], [4], [5], [6], [7], [8], [9],
takenTexts :

在前一种形式中,Take()所需元素的数量是从头开始指定的。
但是,您的需求可能是指定条件而不是数字。

在这种情况下TakeWhile()
您可以在参数中描述条件。

MSDN
public static IEnumerable<TSource> TakeWhile<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate );

代码示例:

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" };

        // 小于4的值
        IEnumerable<int>    takenNumbers    = numbers.TakeWhile( value => value < 4 );
        // 结尾为n
        IEnumerable<string> takenTexts      = texts.TakeWhile( value => value.EndsWith( "n" )  );

        System.Console.WriteLine( "takenNumbers:{0}", takenNumbers.Text() );
        System.Console.WriteLine( "takenTexts  :{0}", takenTexts.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;
    }
}

takenNumbers:[0], [1], [2], [3],
takenTexts :[Sun], [Mon],

TakeWhile()指定条件时,不仅可以获得每个元素的信息,而且可以获得每个元素的索引。
MSDN
public static IEnumerable<TSource> TakeWhile<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" };

        // 值小于索引
        IEnumerable<int>    takenNumbers    = numbers.TakeWhile( ( value, index ) => value > index );
        // 值的长度大于索引
        IEnumerable<string> takenTexts      = texts.TakeWhile( ( value, index ) => value.Length > index );
        
        System.Console.WriteLine( "takenNumbers:{0}", takenNumbers.Text() );
        System.Console.WriteLine( "takenTexts  :{0}", takenTexts.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;
    }
}

takenNumbers:[9], [8], [7], [6], [5],
takenTexts :[Sun], [Mon], [Tue],

TakeWhile()和Where()的区别

有一个类似的LINQ函数Where()

MSDN
public static IEnumerable<TSource> Where<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate );

Where()用于获取符合条件的元素。
让我们用Where()TakeWhile()进行比较。

以下示例描述了获取元素低于指定数字的条件。

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>    takenNumbers    = numbers.TakeWhile( value => value < 5 );
        // 值小于5
        IEnumerable<int>    whereNumbers    = numbers.Where( value => value < 5 );

        System.Console.WriteLine( "takenNumbers:{0}", takenNumbers.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;
    }
} 

takenNumbers:[0], [1], [2], [3], [4],
whereNumbers:[0], [1], [2], [3], [4],

我得到了相同的结果。
不过我们采取的是升序,现在我们打乱元素继续尝试。

代码示例:

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>    takenNumbers    = numbers.TakeWhile( value => value < 5 );
        // 小于5
        IEnumerable<int>    whereNumbers    = numbers.Where( value => value < 5 );

        System.Console.WriteLine( "takenNumbers:{0}", takenNumbers.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;
    }
} 

takenNumbers:[0], [3],
whereNumbers:[0], [3], [1], [4], [2],

结果发生变化。
由此,我们可以得出结论:
Where()获取符合条件的所有元素
TakeWhile()是从头开始判断,遇到不满足条件的就中止,无论后续是否还有符合条件的元素。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我寄人间雪满头丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值