[.net] LINQ where vs takewhile

takewhile과 where LINQ methods 사이의 차이를 얻고 싶습니다 .MSDN에서 다음 데이터를 얻었습니다.하지만 나에게 의미가 없습니다.

Where<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>) 

술어를 기반으로 일련의 값을 필터링합니다.

TakeWhile<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)

지정된 조건이 참이면 시퀀스에서 요소를 반환합니다.

모든 의견을 환영합니다.



답변

조건이 false이면 TakeWhile이 중지되고 Where가 계속되고 조건과 일치하는 모든 요소를 ​​찾습니다.

var intList = new int[] { 1, 2, 3, 4, 5, -1, -2 };
Console.WriteLine("Where");
foreach (var i in intList.Where(x => x <= 3))
    Console.WriteLine(i);
Console.WriteLine("TakeWhile");
foreach (var i in intList.TakeWhile(x => x <= 3))
    Console.WriteLine(i);

제공

Where
1
2
3
-1
-2
TakeWhile
1
2
3


답변

Where 일치를 찾는 전체 시퀀스를 검사 할 수 있습니다.

Enumerable.Range(1, 10).Where(x => x % 2 == 1)
// 1, 3, 5, 7, 9

TakeWhile 첫 번째 불일치가 발생하면 검색을 중지합니다.

Enumerable.Range(1, 10).TakeWhile(x => x % 2 == 1)
// 1


답변

포함하는 배열이 있다고 가정합니다 [1, 3, 5, 7, 9, 0, 2, 4, 6, 8]. 지금:

var whereTest = array.Where(i => i <= 5);반환 [1, 3, 5, 0, 2, 4]됩니다.

var whileTest = array.TakeWhile(i => i <= 5);반환 [1, 3, 5]됩니다.


답변

MSDN 말한다

Enumerable.TakeWhile Method

지정된 조건이 참이면 시퀀스에서 요소를 반환 한 다음 나머지 요소를 건너 뜁니다.

Enumerable.Where

술어를 기반으로 일련의 값을 필터링합니다.

차이점은 조건과 일치하는지 여부에 관계없이 첫 번째 불일치에서 나머지 요소Enumerable.TakeWhile 건너 뜁니다.


답변

기존 답변은 정확하지만 결과가 같을 경우 TakeWhile을 사용하려는 이유 를 지적하지 않습니다 . 성능. 20 억 개의 항목이있는 정렬 된 목록이 있고 주어진 값보다 적은 항목 (아마도 10 개 또는 15 개 항목)을 원한다고 가정합니다. Where 절은 20 억 개의 항목을 모두 검사하고 TakeWhile은 제공된 값보다 크거나 같은 값을 찾는 즉시 중지됩니다.


답변

전달 된 시퀀스의 순서는에서 절대적으로 중요 TakeWhile합니다.는 술어가를 반환하는 즉시 종료되는 false반면 Where첫 번째 false값 이후의 시퀀스를 계속 평가합니다 .

에 대한 일반적인 사용 TakeWhile은 시퀀스 순서에 대한 추가 지식이있을 수있는 크고 비싸거나 무한한 열거 형을 지연 평가하는 동안입니다.

예 : 주어진 순서 :

IEnumerable<BigInteger> InfiniteSequence()
{
    BigInteger sequence = 0;
    while (true)
    {
        yield return sequence++;
    }
}

A .Where는 열거 형의 일부를 평가하려는 무한 루프를 발생시킵니다.

var result = InfiniteSequence()
    .Where(n => n < 100)
    .Count();

반면 a .TakeWhile, 그리고 열거 형이 오름차순이라는 지식으로 무장하면 부분 시퀀스를 평가할 수 있습니다.

var result = InfiniteSequence()
    .TakeWhile(n => n < 100)
    .Count();


답변