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()
是从头开始判断,遇到不满足条件的就中止,无论后续是否还有符合条件的元素。