문제

나는 종종 다음과 같은 코드를 작성하고 있습니다.

List<int> list = new List<int> { 1, 3, 5 };
foreach (int i in list) {
    Console.Write("{0}\t", i.ToString()); }
Console.WriteLine();

다음과 같은 것이 더 좋습니다:

List<int> list = new List<int> { 1, 3, 5 };
Console.WriteLine("{0}\t", list);

나는 이것을 수행하는 영리한 방법이 있다고 생각하지만 그것을 볼 수 없습니다.첫 번째 블록보다 더 나은 솔루션을 가진 사람이 있습니까?

도움이 되었습니까?

해결책

이 작업을 수행:

list.ForEach(i => Console.Write("{0}\t", i));

편집하다:응답한 다른 사람들에게 - 그는 그들 사이에 탭을 사용하여 모두 같은 줄에 있기를 원합니다.:)

다른 팁

재미를 위한 다른 접근 방식:

Console.WriteLine(string.Join("\t", list));

Don't Repeat Yourself에 따라 항상 반복하는 코드가 있는 경우 해당 코드를 자신의 라이브러리에 넣고 호출해야 합니다.이를 염두에 두고 올바른 답을 얻으려면 두 가지 측면이 있습니다.첫 번째는 라이브러리 함수를 호출하는 코드의 명확성과 간결성입니다.두 번째는 foreach의 성능 영향입니다.

먼저 호출 코드의 명확성과 간결성에 대해 생각해 보겠습니다.

foreach는 다양한 방법으로 수행할 수 있습니다.

  1. for 루프
  2. foreach 루프
  3. 컬렉션.ForEach

foreach List.ForEach를 람바와 함께 수행하는 모든 방법 중에서 가장 명확하고 간단합니다.

list.ForEach(i => Console.Write("{0}\t", i));

따라서 이 단계에서는 List.ForEach처럼 보일 수 있습니다.그런데 이거 성능이 어떤가요?이 경우 콘솔에 쓰는 시간이 코드 성능을 좌우한다는 것은 사실입니다.특정 언어 기능의 성능에 대해 알고 있다면 적어도 그것을 고려해야 합니다.

에 따르면 Duston Campbell의 foreach 성능 측정 최적화된 코드에서 목록을 반복하는 가장 빠른 방법은 List.Count를 호출하지 않고 for 루프를 사용하는 것입니다.

그러나 for 루프는 장황한 구조입니다.이는 또한 기능적 관용구에 대한 현재 추세와 일치하지 않는 작업을 수행하는 매우 반복적인 방법으로 간주됩니다.

그렇다면 간결성, 명확성 및 성능을 얻을 수 있습니까?확장 방법을 사용하면 가능합니다.이상적인 세계에서는 목록을 가져와 구분 기호로 쓰는 콘솔 확장 메서드를 만드는 것이 좋습니다.콘솔은 정적 클래스이고 확장 메서드는 클래스 인스턴스에서만 작동하기 때문에 이 작업을 수행할 수 없습니다.대신에 우리는 (David B의 제안에 따라) 목록 자체에 확장 메소드를 넣어야 합니다:

public static void WriteLine(this List<int> theList)
{
  foreach (int i in list)
  {
    Console.Write("{0}\t", t.ToString());
  }
  Console.WriteLine();
}

이 코드는 여러 곳에서 사용될 예정이므로 다음과 같은 개선 작업을 수행해야 합니다.

  • foreach를 사용하는 대신 캐시된 개수가 있는 for 루프인 컬렉션을 반복하는 가장 빠른 방법을 사용해야 합니다.
  • 현재는 List만 인수로 전달할 수 있습니다.라이브러리 기능으로서 우리는 약간의 노력을 통해 이를 일반화할 수 있습니다.
  • List를 사용하면 List만 사용할 수 있으며, IList를 사용하면 이 코드를 Array에서도 사용할 수 있습니다.
  • 확장 메소드는 IList에 있으므로 작성 대상을 더 명확하게 하기 위해 이름을 변경해야 합니다.

함수의 코드는 다음과 같습니다.

public static void WriteToConsole<T>(this IList<T> collection)
{
    int count = collection.Count();
    for(int i = 0;  i < count; ++i)
    {
        Console.Write("{0}\t", collection[i].ToString(), delimiter);
    }
    Console.WriteLine();
}

클라이언트가 구분 기호를 전달하도록 허용하면 이를 더욱 향상시킬 수 있습니다.그런 다음 다음과 같이 표준 구분 기호를 사용하여 콘솔에 쓰는 두 번째 함수를 제공할 수 있습니다.

public static void WriteToConsole<T>(this IList<T> collection)
{
    WriteToConsole<T>(collection, "\t");
}

public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
    int count = collection.Count();
    for(int i = 0;  i < count; ++i)
    {
         Console.Write("{0}{1}", collection[i].ToString(), delimiter);
    }
    Console.WriteLine();
}

이제 우리는 콘솔에 목록을 작성하는 간단하고 명확하며 성능이 뛰어난 방법을 원하므로 하나를 가지고 있습니다.다음은 라이브러리 기능 사용 데모를 포함한 전체 소스 코드입니다.

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

namespace ConsoleWritelineTest
{
    public static class Extensions
    {
        public static void WriteToConsole<T>(this IList<T> collection)
        {
            WriteToConsole<T>(collection, "\t");
        }

        public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
        {
            int count = collection.Count();
            for(int i = 0;  i < count; ++i)
            {
                Console.Write("{0}{1}", collection[i].ToString(), delimiter);
            }
            Console.WriteLine();
        }
    }

    internal class Foo
    {
        override public string ToString()
        {
            return "FooClass";
        }
    }

    internal class Program
    {

        static void Main(string[] args)
        {
            var myIntList = new List<int> {1, 2, 3, 4, 5};
            var myDoubleList = new List<double> {1.1, 2.2, 3.3, 4.4};
            var myDoubleArray = new Double[] {12.3, 12.4, 12.5, 12.6};
            var myFooList = new List<Foo> {new Foo(), new Foo(), new Foo()};
            // Using the standard delimiter /t
            myIntList.WriteToConsole();
            myDoubleList.WriteToConsole();
            myDoubleArray.WriteToConsole();
            myFooList.WriteToConsole();
            // Using our own delimiter ~
            myIntList.WriteToConsole("~");
            Console.Read();
        }
    }
}

=======================================================

이것이 대답의 끝이라고 생각할 수도 있습니다.그러나 추가로 일반화할 수 있는 부분이 있습니다.fatcat이 항상 콘솔에 글을 쓰고 있는지는 질문에서 명확하지 않습니다.아마도 foreach에서 다른 작업을 수행해야 할 수도 있습니다.이 경우 Jason Bunting의 답변이 일반성을 제공할 것입니다.그의 대답은 다음과 같습니다.

list.ForEach(i => Console.Write("{0}\t", i));

확장 메서드를 한 번 더 개선하고 아래와 같이 FastForEach를 추가하지 않는 한 그렇습니다.

public static void FastForEach<T>(this IList<T> collection, Action<T> actionToPerform)
    {
        int count = collection.Count();
        for (int i = 0; i < count; ++i)
        {
            actionToPerform(collection[i]);    
        }
        Console.WriteLine();
    }

이를 통해 컬렉션의 모든 요소에 대해 임의의 코드를 실행할 수 있습니다. 가능한 가장 빠른 반복 방법을 사용하여.

FastForEach를 사용하도록 WriteToConsole 함수를 변경할 수도 있습니다.

public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
     collection.FastForEach(item => Console.Write("{0}{1}", item.ToString(), delimiter));
}

이제 FastForEach의 사용 예를 포함한 전체 소스 코드는 다음과 같습니다.

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

namespace ConsoleWritelineTest
{
    public static class Extensions
    {
        public static void WriteToConsole<T>(this IList<T> collection)
        {
            WriteToConsole<T>(collection, "\t");
        }

        public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
        {
             collection.FastForEach(item => Console.Write("{0}{1}", item.ToString(), delimiter));
        }

        public static void FastForEach<T>(this IList<T> collection, Action<T> actionToPerform)
        {
            int count = collection.Count();
            for (int i = 0; i < count; ++i)
            {
                actionToPerform(collection[i]);    
            }
            Console.WriteLine();
        }
    }

    internal class Foo
    {
        override public string ToString()
        {
            return "FooClass";
        }
    }

    internal class Program
    {

        static void Main(string[] args)
        {
            var myIntList = new List<int> {1, 2, 3, 4, 5};
            var myDoubleList = new List<double> {1.1, 2.2, 3.3, 4.4};
            var myDoubleArray = new Double[] {12.3, 12.4, 12.5, 12.6};
            var myFooList = new List<Foo> {new Foo(), new Foo(), new Foo()};

            // Using the standard delimiter /t
            myIntList.WriteToConsole();
            myDoubleList.WriteToConsole();
            myDoubleArray.WriteToConsole();
            myFooList.WriteToConsole();

            // Using our own delimiter ~
            myIntList.WriteToConsole("~");

            // What if we want to write them to separate lines?
            myIntList.FastForEach(item => Console.WriteLine(item.ToString()));
            Console.Read();
        }
    }
}

새 목록 { 1, 3, 5 }.ForEach(Console.WriteLine);

        List<int> a = new List<int>() { 1, 2, 3, 4, 5 };
        a.ForEach(p => Console.WriteLine(p));

편집하다:아아아 그 사람이 날 이겼어.

list.ForEach(x=>Console.WriteLine(x));
List<int> list = new List<int> { 1, 3, 5 };
list.ForEach(x => Console.WriteLine(x));

편집하다:젠장!테스트하기 위해 Visual Studio를 여는 데 너무 오랜 시간이 걸렸습니다.

또한 다음과 같이 가입할 수도 있습니다.

var qwe = new List<int> {5, 2, 3, 8};
Console.WriteLine(string.Join("\t", qwe));
public static void WriteLine(this List<int> theList)
{
  foreach (int i in list)
  {
    Console.Write("{0}\t", t.ToString());
  }
  Console.WriteLine();
}

그럼 나중에...

list.WriteLine();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top