LINQ where vs takewhile


99

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

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

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

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

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

모든 의견을 환영합니다.


1
좋은 질문입니다. TakeWhile의 Intellisense는 여전히 "지정된 조건이 참인 한 요소를 반환합니다."라고 말합니다. 이것은 Where와 동일하게 해석 될 수 있습니다. 문구는 "조건이 거짓으로 평가 될 때까지 ... 요소를 반환합니다"와 같은 형식이어야합니다.
Peter

답변:


159

조건이 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

30

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

9

포함하는 배열이 있다고 가정합니다 [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]됩니다.


whileTest는 @David B 및 @Albin Sunnanbo 답변에 따라 1 개만 반환 할 것이라고 생각합니다.
Mohammed Thabet

아니요, 조건이 충족되지 않을 때까지 항목을 반환합니다. 이 경우 1, 3 및 5가 조건을 충족합니다 (<= 5).
Jim Mischel

8

MSDN 말한다

Enumerable.TakeWhile Method

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

Enumerable.Where

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

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


6

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


5

전달 된 시퀀스의 순서는에서 절대적으로 중요 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();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.