C #에서 목록의 첫 번째 N 요소를 얻는 방법은 무엇입니까?


384

Linq를 사용하여 프로젝트에서 버스 일정을 쿼리하여 언제든지 다음 5 개의 버스 도착 시간을 얻을 수 있습니다. 검색어를 처음 5 개의 결과로 제한하려면 어떻게해야합니까?

더 일반적으로 C #에서 목록을 어떻게 가져갈 수 있습니까? (파이썬에서는 mylist[:5]처음 5 개의 요소를 얻는 데 사용 합니다.)

답변:


706
var firstFiveItems = myList.Take(5);

또는 슬라이스 :

var secondFiveItems = myList.Skip(5).Take(5);

물론 어떤 종류의 순서에 따라 처음 다섯 개의 항목을 얻는 것이 편리합니다.

var firstFiveArrivals = myList.OrderBy(i => i.ArrivalTime).Take(5);

87
예를 들어 목록에 3 개의 항목 만있는 경우 예외가 발생합니까? 아니면 최대 5 개까지 걸릴까요?
bobek

87
@bobek : 예외가 발생하지 않습니다. 요소가 충분하지 않으면 가지고있는 것을 반환합니다.
Joshua Pech

1
정확히 예외는 건너 뛰기 발생하지 내가 어떤 일반적인 수집 및 처리 배치 당 X 항목을 가지고 원하는대로 가져 가라 내 문제를 해결 합친
JohanLarsson

.Take(n)TakeIterator 를 리턴 한다는 점에 유의해야 합니다. n요소가 있는 목록을 반환하지 않습니다 (많은 것을 사용할 수 있다고 가정). 사용 .ToArray()또는 .ToList()의 결과에는 Take구체적인 배열 또는 목록을 얻을 수 있습니다.
Andrew Webb

69

질문 이이 버전을 요구하지 않더라도 누구나 관심이있는 경우 C # 2에서는 다음과 같습니다.

myList.Sort(CLASS_FOR_COMPARER);
List<string> fiveElements = myList.GetRange(0, 5);

익명의 술어도 추가 할 수 있습니까?
AlexeyMK

2
List <T> .Sort는 void를 반환합니다. 정렬 한 다음 GetRange를 별도로 사용해야합니다. Comparison <T> 익명 메소드를 사용하여 CLASS_FOR_COMPARER의 필요성을 제거 할 수도 있습니다.
Marc Gravell

@AlexeyMK-당신은 술어 (Predicate <T>)가 아닌 Comparison <T>을 의미합니다 – 술어는 데이터를 필터링하는데 사용됩니다
Marc Gravell

이 답변은 10 년이 지난 지금도 많은 C # 버전이 유용하다고 생각합니다. 목록이있는 특정한 경우. 특히 많은 항목을 건너 뛰는 경우. 예를 들어 백만 개의 항목 목록이 있고 목록에서 멀리 떨어진 5 개의 조각을 원합니다. GetRange는 정확히 어디로 가야하는지 알고 있습니다. Skip+ Take가 똑똑한 지 또는 건너 뛴 항목을 열거하는지 여부는 알 수 없습니다 . 그리고 나는 알 필요가 없습니다-나는 단지 GetRange를 사용합니다 (목록을 주었을 때). 두 번째 매개 변수가 마지막 인덱스가 아닌 카운트 인지 확인하십시오 .
ToolmakerSteve

좋은 점은 시퀀스에서 작동하는 요소 수 .Take(n)보다 적은 n요소 가 있으면 걱정할 필요가 없다는 것 입니다. 문제 List<T>.GetRange(0, count)는 당신이 걱정할 필요가 있다는 것입니다 .... 당신은 항목 ArgumentException이없는 경우 얻을 것이다 count.
Andrew Webb

5

pagination당신이 복용을 위해 아래 공식을 사용할 수있는 것처럼 slice of list or elements:

var slice = myList.Skip((pageNumber - 1) * pageSize)
                  .Take(pageSize);

예 1 : 처음 5 개 항목

var pageNumber = 1;
var pageSize = 5;

예 2 : 두 번째 다섯 항목

var pageNumber = 2;
var pageSize = 5;

예 3 : 세 번째 다섯 항목

var pageNumber = 3;
var pageSize = 5;

매개 변수를 공식화 pageSize = 5하고 pageNumber변경하는 경우 슬라이싱에서 항목 수를 변경하려면을 변경하십시오 pageSize.


1

처음 5 개 요소를 가져 오려면 다음과 같이 식을 더 잘 사용하십시오.

var firstFiveArrivals = myList.Where([EXPRESSION]).Take(5);

또는

var firstFiveArrivals = myList.Where([EXPRESSION]).Take(5).OrderBy([ORDER EXPR]);

LINQ 엔진은 실행 지연으로 인해 모든 목록을 검색하지 않고 모든 배열을 정렬하지 않기 때문에 orderBy 변형보다 빠릅니다.

class MyList : IEnumerable<int>
{

    int maxCount = 0;

    public int RequestCount
    {
        get;
        private set;
    }
    public MyList(int maxCount)
    {
        this.maxCount = maxCount;
    }
    public void Reset()
    {
        RequestCount = 0;
    }
    #region IEnumerable<int> Members

    public IEnumerator<int> GetEnumerator()
    {
        int i = 0;
        while (i < maxCount)
        {
            RequestCount++;
            yield return i++;
        }
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    #endregion
}
class Program
{
    static void Main(string[] args)
    {
        var list = new MyList(15);
        list.Take(5).ToArray();
        Console.WriteLine(list.RequestCount); // 5;

        list.Reset();
        list.OrderBy(q => q).Take(5).ToArray();
        Console.WriteLine(list.RequestCount); // 15;

        list.Reset();
        list.Where(q => (q & 1) == 0).Take(5).ToArray();
        Console.WriteLine(list.RequestCount); // 9; (first 5 odd)

        list.Reset();
        list.Where(q => (q & 1) == 0).Take(5).OrderBy(q => q).ToArray();
        Console.WriteLine(list.RequestCount); // 9; (first 5 odd)
    }
}

25
이제 처음 5 개의 요소 만 선택한 경우를 제외하고. 더 빠를 수도 있지만 다른 의미론을 가지고 있기 때문에 사람들이 실제로 달성하고자하는 것보다 적습니다.
Greg Beech
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.