[c#] List <T>에서 모든 n 번째 항목을 어떻게 가져올 수 있습니까?

.NET 3.5를 사용 n하고 있으며 목록에서 * * 번째 항목을 모두 얻을 수 있기를 원합니다 . 람다 식을 사용했는지 LINQ를 사용했는지에 대해서는 신경 쓰지 않습니다.

편집하다

이 질문이 꽤 많은 논쟁을 불러 일으켰던 것 같습니다 (좋은 일 이죠?). 내가 배운 가장 중요한 것은 무언가를하는 모든 방법을 알고 있다고 생각할 때 (이것처럼 간단하더라도) 다시 생각한다는 것입니다!



답변

return list.Where((x, i) => i % nStep == 0);


답변

나는 그것이 “오래된 학교”라는 것을 알고 있지만, 왜 stepping = n과 함께 for 루프를 사용하지 않는가?


답변

처럼 들린다

IEnumerator<T> GetNth<T>(List<T> list, int n) {
  for (int i=0; i<list.Count; i+=n)
    yield return list[i]
}

트릭을 할 것입니다. Linq 또는 람다 식을 사용할 필요가 없다고 생각합니다.

편집하다:

그것을 만드십시오

public static class MyListExtensions {
  public static IEnumerable<T> GetNth<T>(this List<T> list, int n) {
    for (int i=0; i<list.Count; i+=n)
      yield return list[i];
  }
}

LINQish 방식으로 작성합니다.

from var element in MyList.GetNth(10) select element;

2 차 편집 :

더 LINQish로 만들기 위해

from var i in Range(0, ((myList.Length-1)/n)+1) select list[n*i];


답변

요소와 함께 인덱스를 전달하는 Where 오버로드를 사용할 수 있습니다.

var everyFourth = list.Where((x,i) => i % 4 == 0);


답변

For 루프

for(int i = 0; i < list.Count; i += n)
    //Nth Item..


답변

LINQ 식으로 할 수 있는지 확실하지 않지만 Where확장 메서드를 사용하여 수행 할 수 있다는 것을 알고 있습니다 . 예를 들어 모든 다섯 번째 항목을 얻으려면 :

List<T> list = originalList.Where((t,i) => (i % 5) == 0).ToList();

이것은 거기에서 첫 번째 항목과 매 다섯 번째 항목을 가져옵니다. 첫 번째 항목이 아닌 다섯 번째 항목에서 시작하려면 0과 비교하는 대신 4와 비교합니다.


답변

linq 확장을 제공하면 최소한의 특정 인터페이스, 따라서 IEnumerable에서 작업 할 수 있어야한다고 생각합니다. 물론, 특히 큰 N에 대해 속도를 내고 있다면 인덱스 액세스에 과부하를 제공 할 수 있습니다. 후자는 필요하지 않은 많은 양의 데이터를 반복 할 필요가 없으며 Where 절보다 훨씬 빠릅니다. 두 오버로드를 모두 제공하면 컴파일러가 가장 적합한 변형을 선택할 수 있습니다.

public static class LinqExtensions
{
    public static IEnumerable<T> GetNth<T>(this IEnumerable<T> list, int n)
    {
        if (n < 0)
            throw new ArgumentOutOfRangeException("n");
        if (n > 0)
        {
            int c = 0;
            foreach (var e in list)
            {
                if (c % n == 0)
                    yield return e;
                c++;
            }
        }
    }
    public static IEnumerable<T> GetNth<T>(this IList<T> list, int n)
    {
        if (n < 0)
            throw new ArgumentOutOfRangeException("n");
        if (n > 0)
            for (int c = 0; c < list.Count; c += n)
                yield return list[c];
    }
}