programing

IE 숫자에서 항목을 반복하지 않고 카운트하시겠습니까?

linuxpc 2023. 5. 1. 20:01
반응형

IE 숫자에서 항목을 반복하지 않고 카운트하시겠습니까?

private IEnumerable<string> Tables
{
    get
    {
        yield return "Foo";
        yield return "Bar";
    }
}

제가 그것들을 반복해서 #m의 #n 처리와 같은 것을 쓰고 싶다고 가정해 보겠습니다.

메인 반복 전에 반복하지 않고 m의 값을 알 수 있는 방법이 있습니까?

제가 분명히 말했길 바랍니다.

IEnumerable지원하지 않습니다.이것은 의도적인 것입니다. IEnumerable에서는 게으른 평가를 사용하여 필요하기 직전에 요청한 요소를 가져옵니다.

반하지않항수알를싶사수있다용습니할다면고복목고▁without▁ 사용하면 됩니다.ICollection<T>그것은 있습니다.Count소유물.

System.Linq.Enumerable.Count에 대한 IEnumerable<T>에는 다음과 같은 구현이 있습니다.

ICollection<T> c = source as ICollection<TSource>;
if (c != null)
    return c.Count;

int result = 0;
using (IEnumerator<T> enumerator = source.GetEnumerator())
{
    while (enumerator.MoveNext())
        result++;
}
return result;

그래서 캐스팅을 하려고 합니다.ICollection<T>이 있는Count가능하면 자산을 사용합니다.그렇지 않으면 반복됩니다.

은 그서당최방법은선을 하는 것입니다.Count()에 있는 IEnumerable<T>가능한 최고의 성능을 얻을 수 있기 때문입니다.

정보를 추가하는 중입니다.

Count()확장이 항상 반복되는 것은 아닙니다.카운트가 데이터베이스로 이동하지만 모든 행을 가져오는 대신 SQL을 실행하는 Linkq to Sql을 고려합니다.Count()명령을 실행하고 대신 결과를 반환합니다.

런타임를 또한컴또는러호객수똑다체똑니정합있출도라고 부를 정도로 .Count()방법(있는 경우).그래서 다른 응답자들이 말하는 것처럼 완전히 무지하고 요소를 세기 위해 항상 반복하는 것은 아닙니다.

프로그래머가 그냥 확인하는 경우가 많습니다.if( enumerable.Count != 0 ) 사용Any()확장메서드, 들감어예와 같이if( enumerable.Any() )요소가 더 효율적입니다. linq 게 으 평 의 요 가 는 있 입 적 니 효 율 다 더 씬 훨 에 때 문 있 기 수 될 단 락 하 면 단 른 판 소 다 가 고 ▁is 니 ▁as uation ▁with 다 입 lin 적 q ▁more ▁it ▁lin ▁short q ▁efficient s ▁it ▁far ▁eval 율 ' ▁determine 더 .

제 친구 중 한 명이 블로그 게시물을 여러 개 가지고 있는데, 이 게시물은 당신이 이것을 할 수 없는 이유를 설명해 줍니다.는 각 이 다음 하는 IE . 서 그는 IE number를 반환합니다.ulong.MaxValue다음 항목은 당신이 요청할 때까지 계산되지 않습니다.빠른 팝업 질문: 몇 개의 항목이 반환됩니까?

게시물은 다음과 같습니다. 하지만 좀 깁니다.

  1. Beyond Loops(다른 게시물에 사용되는 초기 EnumerableUtility 클래스 제공)
  2. 반복 적용(초기 구현)
  3. 크레이지 확장 방법: 작업 지연 목록(성능 최적화)

또는 다음을 수행할 수 있습니다.

Tables.ToList<string>().Count;

IEnumberable은 반복하지 않고 셀 수 없습니다.

"정상" 상황에서 List<T>와 같은 IEnumberable 또는 IEnumberable<T>를 구현하는 클래스는 List<T>를 반환하여 Count 메서드를 구현할 수 있습니다.속성을 카운트합니다.그러나 Count 방법은 실제로 IEnumberable에 정의된 방법이 아닙니다.<또는 IEnumberable 인터페이스.(사실 GetEnumerator뿐입니다.)이는 클래스별 구현을 제공할 수 없음을 의미합니다.

카운트는 정적 클래스 Enumerable에 정의된 확장 메서드입니다.즉, IEnumberable의 모든 인스턴스에서 호출할 수 있습니다.<파생 클래스(해당 클래스의 구현에 관계없이).그러나 이는 또한 이러한 클래스 외부의 단일 장소에서 구현된다는 것을 의미합니다.물론 이는 이 클래스의 내부와 완전히 독립적인 방식으로 구현되어야 한다는 것을 의미합니다.계산을 수행하는 유일한 방법은 반복입니다.

아니요, 일반적으로 아닙니다.열거형을 사용할 때 한 가지 중요한 점은 열거형의 실제 개체 집합을 미리 알 수 없거나 아예 알 수 없다는 것입니다.

시스템을 사용할 수 있습니다.린크.

using System;
using System.Collections.Generic;
using System.Linq;

public class Test
{
    private IEnumerable<string> Tables
    {
        get {
             yield return "Foo";
             yield return "Bar";
         }
    }

    static void Main()
    {
        var x = new Test();
        Console.WriteLine(x.Tables.Count());
    }
}

결과는 '2'입니다.

가장 쉬운 방법은

Enumerable.Count<TSource>(IEnumerable<TSource> source)

참조: system.linq.enumberable

당신의 즉각적인 질문(부정적으로 철저히 답변됨)을 넘어 열거형을 처리하는 동안 진행 상황을 보고하려면 제 블로그 게시물인 링크 쿼리 중 진행 상황 보고를 참조하십시오.

이를 통해 다음을 수행할 수 있습니다.

BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += (sender, e) =>
      {
          // pretend we have a collection of 
          // items to process
          var items = 1.To(1000);
          items
              .WithProgressReporting(progress => worker.ReportProgress(progress))
              .ForEach(item => Thread.Sleep(10)); // simulate some real work
      };

나는 전달된 사람을 확인하기 위해 메소드 안에서 그런 방법을 사용했습니다.IEnumberable

if( iEnum.Cast<Object>().Count() > 0) 
{

}

다음과 같은 방법 내부:

GetDataTable(IEnumberable iEnum)
{  
    if (iEnum != null && iEnum.Cast<Object>().Count() > 0) //--- proceed further

}

의 버전에 따라 다릅니다.IEnumberable 개체의 Net 및 구현.Microsoft는 IE 번호를 수정했습니다.구현을 확인하는 카운트 방법이며, I 컬렉션을 사용합니다.카운트 또는 I 수집 < TSource >.카운트, 자세한 내용은 여기를 참조하십시오. https://connect.microsoft.com/VisualStudio/feedback/details/454130

아래는 Ildasm for System의 MSIL입니다.핵심, 여기서 시스템.Linq가 상주합니다.

.method public hidebysig static int32  Count<TSource>(class 

[mscorlib]System.Collections.Generic.IEnumerable`1<!!TSource> source) cil managed
{
  .custom instance void System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       85 (0x55)
  .maxstack  2
  .locals init (class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource> V_0,
           class [mscorlib]System.Collections.ICollection V_1,
           int32 V_2,
           class [mscorlib]System.Collections.Generic.IEnumerator`1<!!TSource> V_3)
  IL_0000:  ldarg.0
  IL_0001:  brtrue.s   IL_000e
  IL_0003:  ldstr      "source"
  IL_0008:  call       class [mscorlib]System.Exception System.Linq.Error::ArgumentNull(string)
  IL_000d:  throw
  IL_000e:  ldarg.0
  IL_000f:  isinst     class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource>
  IL_0014:  stloc.0
  IL_0015:  ldloc.0
  IL_0016:  brfalse.s  IL_001f
  IL_0018:  ldloc.0
  IL_0019:  callvirt   instance int32 class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource>::get_Count()
  IL_001e:  ret
  IL_001f:  ldarg.0
  IL_0020:  isinst     [mscorlib]System.Collections.ICollection
  IL_0025:  stloc.1
  IL_0026:  ldloc.1
  IL_0027:  brfalse.s  IL_0030
  IL_0029:  ldloc.1
  IL_002a:  callvirt   instance int32 [mscorlib]System.Collections.ICollection::get_Count()
  IL_002f:  ret
  IL_0030:  ldc.i4.0
  IL_0031:  stloc.2
  IL_0032:  ldarg.0
  IL_0033:  callvirt   instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<!!TSource>::GetEnumerator()
  IL_0038:  stloc.3
  .try
  {
    IL_0039:  br.s       IL_003f
    IL_003b:  ldloc.2
    IL_003c:  ldc.i4.1
    IL_003d:  add.ovf
    IL_003e:  stloc.2
    IL_003f:  ldloc.3
    IL_0040:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
    IL_0045:  brtrue.s   IL_003b
    IL_0047:  leave.s    IL_0053
  }  // end .try
  finally
  {
    IL_0049:  ldloc.3
    IL_004a:  brfalse.s  IL_0052
    IL_004c:  ldloc.3
    IL_004d:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
    IL_0052:  endfinally
  }  // end handler
  IL_0053:  ldloc.2
  IL_0054:  ret
} // end of method Enumerable::Count

LINQ에는 에 대한 새로운 방법이 있습니다.NET 6 시청 https://www.youtube.com/watch?v=sIXKpyhxHR8

Tables.TryGetNonEnumeratedCount(out var count)

IE 수치의 결과입니다.카운트() 함수가 잘못되었을 수 있습니다.다음은 테스트할 매우 간단한 샘플입니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;

namespace Test
{
  class Program
  {
    static void Main(string[] args)
    {
      var test = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
      var result = test.Split(7);
      int cnt = 0;

      foreach (IEnumerable<int> chunk in result)
      {
        cnt = chunk.Count();
        Console.WriteLine(cnt);
      }
      cnt = result.Count();
      Console.WriteLine(cnt);
      Console.ReadLine();
    }
  }

  static class LinqExt
  {
    public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, int chunkLength)
    {
      if (chunkLength <= 0)
        throw new ArgumentOutOfRangeException("chunkLength", "chunkLength must be greater than 0");

      IEnumerable<T> result = null;
      using (IEnumerator<T> enumerator = source.GetEnumerator())
      {
        while (enumerator.MoveNext())
        {
          result = GetChunk(enumerator, chunkLength);
          yield return result;
        }
      }
    }

    static IEnumerable<T> GetChunk<T>(IEnumerator<T> source, int chunkLength)
    {
      int x = chunkLength;
      do
        yield return source.Current;
      while (--x > 0 && source.MoveNext());
    }
  }
}

결과는 (7,7,3,3)이어야 하지만 실제 결과는 (7,7,3,17)입니다.

여기 게으른 평가와 지연된 실행에 대한 훌륭한 논의가 있습니다.기본적으로 그 가치를 얻으려면 목록을 구체화해야 합니다.

제가 찾은 가장 좋은 방법은 숫자를 목록으로 변환하는 것입니다.

IEnumerable<T> enumList = ReturnFromSomeFunction();

int count = new List<T>(enumList).Count;

모든 답변을 단순화합니다.

IEnumberable에 Count 함수 또는 속성이 없습니다.이 값을 얻으려면 카운트 변수(예: 각 변수)를 저장하거나 Linq를 사용하여 카운트를 구하는 방법을 해결할 수 있습니다.

다음이 있는 경우:

IEnumberable <> 제품

그러면:

선언: "시스템 사용"린크;"

카운트:

상품들.목록으로().세어보세요

ToList에 전화하는 것이 좋습니다.예, 초기에 열거를 수행하고 있지만 여전히 항목 목록에 액세스할 수 있습니다.

최상의 성능을 제공하지는 않지만 LINQ를 사용하여 IE 숫자에 포함된 요소를 셀 수 있습니다.

public int GetEnumerableCount(IEnumerable Enumerable)
{
    return (from object Item in Enumerable
            select Item).Count();
}

사용합니다IEnum<string>.ToArray<string>().Length그리고 그것은 잘 작동합니다.

문자열 목록이 있는 경우 이러한 코드를 사용합니다.

((IList<string>)Table).Count

언급URL : https://stackoverflow.com/questions/168901/count-the-items-from-a-ienumerablet-without-iterating

반응형