문제

나는 다음을 사용할 수 있다는 것을 안다. for 문을 실행하고 동일한 효과를 얻을 수 있지만 foreach C#의 루프?

도움이 되었습니까?

해결책

목록으로 작업 할 때 (직접 인덱싱) for 고리.

편집 : 그것은 일반적으로 당신이있을 때를 의미합니다 할 수 있는 사용하려면 for 루프,이 작업에 대한 올바른 방법 일 수 있습니다. 또한,만큼 foreach 사산으로 구현되며, 구조 자체는 요소 인덱스 및 반복 순서와 무관 한 루프를 표현하기 위해 구축되었으며, 이는 특히 중요합니다. 병렬 프로그래밍. 그것은이다 내 의견 주문에 의존하는 반복은 사용해서는 안됩니다 foreach 루핑을 위해.

다른 팁

.NET 3.5에있는 경우 다음을 수행 할 수 있습니다.

IEnumerable<int> enumerableThing = ...;
foreach (var x in enumerableThing.Reverse())

기본적으로 열거자를 통해 모든 것을 스택에 올려 놓고 역순으로 모든 것을 다시 튀어 나와야하기 때문에 그다지 효율적이지 않습니다.

직접적으로 명시적인 컬렉션 (예 : Ilist)이있는 경우 for 대신 루프.

.NET 2.0에 있고 for 루프를 사용할 수없는 경우 (예 : ienumerable이 있습니다) 자신의 역 함수를 작성하면됩니다. 이것은 작동해야합니다 :

static IEnumerable<T> Reverse<T>(IEnumerable<T> input)
{
    return new Stack<T>(input);
}

이것은 아마도 명백하지 않은 행동에 의존합니다. 스택 생성자에게 ienumerable을 통과하면 반복을 반복하여 항목을 스택에 밀어 넣습니다. 그런 다음 스택을 통해 반복하면 물건을 역 순서로 다시 튀어 나옵니다.

이것과 .NET 3.5 Reverse() 확장 방법은 반환 품목을 절대 멈추지 않도록 ienumerable을 먹이면 분명히 폭발합니다.

280Z28이 말했듯이 IList<T> 그냥 인덱스를 사용해도 됩니다.확장 메서드에서 이를 숨길 수 있습니다.

public static IEnumerable<T> FastReverse<T>(this IList<T> items)
{
    for (int i = items.Count-1; i >= 0; i--)
    {
        yield return items[i];
    }
}

이 것보다 더 빠를 거예요 Enumerable.Reverse() 모든 데이터를 먼저 버퍼링합니다.(나는 믿지 않는다 Reverse 다음과 같은 방식으로 최적화가 적용되었습니다. Count() 않습니다.) 이 버퍼링은 처음 반복을 시작할 때 데이터가 완전히 읽혀진다는 것을 의미합니다. FastReverse 반복하는 동안 목록에 적용된 모든 변경 사항을 "확인"할 수 있습니다.(반복 사이에 여러 항목을 제거하면 중단됩니다.)

일반 시퀀스의 경우 역순으로 반복할 수 있는 방법이 없습니다. 시퀀스는 무한할 수 있습니다. 예를 들면 다음과 같습니다.

public static IEnumerable<T> GetStringsOfIncreasingSize()
{
    string ret = "";
    while (true)
    {
        yield return ret;
        ret = ret + "x";
    }
}

이를 반대로 반복하려고 하면 어떻게 될까요?

반복에 'foreach'를 사용하기 전에 'Reverse'방법으로 목록을 반대로 반전시킵니다.

    myList.Reverse();
    foreach( List listItem in myList)
    {
       Console.WriteLine(listItem);
    }

목록을 사용하는 경우u003CT> ,이 코드를 사용할 수도 있습니다.

List<string> list = new List<string>();
list.Add("1");
list.Add("2");
list.Add("3");
list.Reverse();

이것은 목록 자체로 목록을 작성하는 메소드입니다.

이제 foreach :

foreach(string s in list)
{
    Console.WriteLine(s);
}

출력은 다음과 같습니다.

3
2
1

때로는 인덱싱의 사치가 없거나 LINQ 쿼리의 결과를 뒤집기를 원하거나 소스 컬렉션을 수정하고 싶지 않을 수도 있습니다.이 중 하나라도 사실이라면 LINQ가 도움을 줄 수 있습니다.

LINQ를 선택한 익명 유형을 사용하는 LINQ 확장 방법은 LINQ OrderByDescending을위한 정렬 키를 제공합니다.

    public static IEnumerable<T> Invert<T>(this IEnumerable<T> source)
    {
        var transform = source.Select(
            (o, i) => new
            {
                Index = i,
                Object = o
            });

        return transform.OrderByDescending(o => o.Index)
                        .Select(o => o.Object);
    }

용법:

    var eable = new[]{ "a", "b", "c" };

    foreach(var o in eable.Invert())
    {
        Console.WriteLine(o);
    }

    // "c", "b", "a"

"반전"과 동의어이기 때문에 "반전"이라고 불리며 목록 리버스 구현으로 명확하게 변환 할 수 있습니다.

int32.minvalue 및 int32.maxvalue는 모든 종류의 수집 인덱스 범위를 벗어나기 때문에 주문 프로세스를 위해이를 활용할 수 있기 때문에 컬렉션의 특정 범위를 뒤집을 수 있습니다. 요소 인덱스가 주어진 범위 아래에있는 경우 int32.maxValue로 할당되어 OrderByDescending을 사용할 때 순서가 변경되지 않도록 지정됩니다. 순서 프로세스의 끝에 나타납니다. 주어진 범위 내의 모든 요소에는 정상 색인이 할당되며 그에 따라 역전됩니다.

    public static IEnumerable<T> Invert<T>(this IEnumerable<T> source, int index, int count)
    {
        var transform = source.Select(
            (o, i) => new
            {
                Index = i < index ? Int32.MaxValue : i >= index + count ? Int32.MinValue : i,
                Object = o
            });

        return transform.OrderByDescending(o => o.Index)
                        .Select(o => o.Object);
    }

용법:

    var eable = new[]{ "a", "b", "c", "d" };

    foreach(var o in eable.Invert(1, 2))
    {
        Console.WriteLine(o);
    }

    // "a", "c", "b", "d"

이러한 LINQ 구현의 성능 히트와 임시 목록을 사용하여 역전을위한 컬렉션을 래핑하는 것을 잘 모르겠습니다.


글을 쓰는 시점에서 나는 LINQ의 자체 역 구현을 알지 못했지만 여전히 재미있었습니다.https://msdn.microsoft.com/en-us/library/vstudio/bb358497(v=vs.100).aspx

아니오.

그것은이다 수집 코드를 변경할 수있는 경우 가능합니다 이는 ienumerable 또는 ienumerable (예 : ILIST의 구현)을 구현합니다.

생성 반복자 예를 들어 다음과 같은 구현과 같이이 작업을 수행합니다. ienumerable 인터페이스 ( '항목'이이 샘플의 목록 필드라고 가정) :

public IEnumerator<TObject> GetEnumerator()
{
    for (var i = items.Count - 1; i >= 0; i--)
    { 
        yield return items[i];
    }
}

IEnumerator IEnumerable.GetEnumerator()
{
    return GetEnumerator();
}

이 때문에 귀하의 목록은 목록을 통해 역순으로 반복합니다.

그냥 힌트 : 문서 내에서 목록 의이 특별한 행동을 명확하게 명시해야합니다 (스택이나 큐와 같은 자체 설명 클래스 이름을 선택함으로써 더 좋습니다).

멋진 대답에 약간의 정교함 존 스키트, 이것은 다재다능 할 수 있습니다 :

public static IEnumerable<T> Directional<T>(this IList<T> items, bool Forwards) {
    if (Forwards) foreach (T item in items) yield return item;
    else for (int i = items.Count-1; 0<=i; i--) yield return items[i];
}

그리고 AS를 사용하십시오

foreach (var item in myList.Directional(forwardsCondition)) {
    .
    .
}

이 코드를 사용했습니다

                if (element.HasAttributes) {

                    foreach(var attr in element.Attributes().Reverse())
                    {

                        if (depth > 1)
                        {
                            elements_upper_hierarchy_text = "";
                            foreach (var ancest  in element.Ancestors().Reverse())
                            {
                                elements_upper_hierarchy_text += ancest.Name + "_";
                            }// foreach(var ancest  in element.Ancestors())

                        }//if (depth > 1)
                        xml_taglist_report += " " + depth  + " " + elements_upper_hierarchy_text+ element.Name + "_" + attr.Name +"(" + attr.Name +")" + "   =   " + attr.Value + "\r\n";
                    }// foreach(var attr in element.Attributes().Reverse())

                }// if (element.HasAttributes) {

이것은 꽤 잘 작동합니다

List<string> list = new List<string>();

list.Add("Hello");
list.Add("Who");
list.Add("Are");
list.Add("You");

foreach (String s in list)
{
    Console.WriteLine(list[list.Count - list.IndexOf(s) - 1]);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top