Frage

Ich schreibe häufig Code wie diesen:

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

Besser wäre so etwas:

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

Ich vermute, dass es dafür eine clevere Möglichkeit gibt, aber ich sehe sie nicht.Hat jemand eine bessere Lösung als den ersten Block?

War es hilfreich?

Lösung

Mach das:

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

BEARBEITEN:An andere, die geantwortet haben – er möchte, dass sie alle in derselben Zeile stehen, mit Tabulatorzeichen dazwischen.:) :)

Andere Tipps

Ein anderer Ansatz, nur zum Spaß:

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

Wenn es einen Code gibt, den Sie gemäß Don't Repeat Yourself ständig wiederholen, sollten Sie ihn in Ihre eigene Bibliothek aufnehmen und so nennen.Vor diesem Hintergrund gibt es zwei Aspekte, um hier die richtige Antwort zu finden.Das erste ist Klarheit und Kürze im Code, der die Bibliotheksfunktion aufruft.Das zweite sind die Auswirkungen von foreach auf die Leistung.

Denken wir zunächst über die Klarheit und Kürze des aufrufenden Codes nach.

Sie können foreach auf verschiedene Arten ausführen:

  1. for-Schleife
  2. foreach-Schleife
  3. Collection.ForEach

Von allen Möglichkeiten, eine foreach List.ForEach mit einem Lamba zu erstellen, ist die klarste und kürzeste.

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

In diesem Stadium könnte es also so aussehen, als wäre List.ForEach der richtige Weg.Doch was ist die Leistung davon?Es stimmt, dass in diesem Fall die Zeit zum Schreiben in die Konsole die Leistung des Codes bestimmt.Wenn wir etwas über die Leistung einer bestimmten Sprachfunktion wissen, sollten wir es auf jeden Fall zumindest in Betracht ziehen.

Entsprechend Duston Campbells Leistungsmessungen von foreach Der schnellste Weg, die Liste unter optimiertem Code zu iterieren, ist die Verwendung einer for-Schleife ohne Aufruf von List.Count.

Die for-Schleife ist jedoch ein ausführliches Konstrukt.Es wird auch als eine sehr iterative Vorgehensweise angesehen, die nicht mit dem aktuellen Trend zu funktionalen Redewendungen übereinstimmt.

Können wir also Kürze, Klarheit und Leistung erreichen?Wir können dies mithilfe einer Erweiterungsmethode tun.In einer idealen Welt würden wir eine Erweiterungsmethode auf der Konsole erstellen, die eine Liste nimmt und sie mit einem Trennzeichen schreibt.Dies ist nicht möglich, da Console eine statische Klasse ist und Erweiterungsmethoden nur für Instanzen von Klassen funktionieren.Stattdessen müssen wir die Erweiterungsmethode in die Liste selbst aufnehmen (gemäß dem Vorschlag von David B):

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

Dieser Code wird an vielen Stellen verwendet, daher sollten wir die folgenden Verbesserungen vornehmen:

  • Anstatt foreach zu verwenden, sollten wir die schnellste Methode zum Iterieren der Sammlung verwenden, nämlich eine for-Schleife mit einer zwischengespeicherten Anzahl.
  • Derzeit kann nur List als Argument übergeben werden.Als Bibliotheksfunktion können wir sie mit geringem Aufwand verallgemeinern.
  • Die Verwendung von List beschränkt uns auf nur Listen. Die Verwendung von IList ermöglicht die Verwendung dieses Codes auch mit Arrays.
  • Da sich die Erweiterungsmethode auf einer IList befindet, müssen wir den Namen ändern, um klarer zu machen, wohin wir schreiben:

So würde der Code für die Funktion aussehen:

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();
}

Wir können dies noch weiter verbessern, indem wir dem Client erlauben, das Trennzeichen zu übergeben.Wir könnten dann eine zweite Funktion bereitstellen, die mit dem Standardtrennzeichen wie folgt in die Konsole schreibt:

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();
}

Da wir nun eine kurze, klare und leistungsstarke Methode zum Schreiben von Listen auf der Konsole benötigen, haben wir eine.Hier ist der gesamte Quellcode, einschließlich einer Demonstration der Verwendung der Bibliotheksfunktion:

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();
        }
    }
}

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

Sie könnten denken, dass dies das Ende der Antwort sein sollte.Es gibt jedoch noch eine weitere Verallgemeinerungsmöglichkeit.Aus der Frage von fatcat geht nicht klar hervor, ob er immer auf die Konsole schreibt.Vielleicht muss im foreach noch etwas anderes gemacht werden.In diesem Fall wird die Antwort von Jason Bunting diese Allgemeingültigkeit vermitteln.Hier noch einmal seine Antwort:

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

Es sei denn, wir verfeinern unsere Erweiterungsmethoden noch einmal und fügen FastForEach wie folgt hinzu:

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();
    }

Dadurch können wir beliebigen Code für jedes Element in der Sammlung ausführen unter Verwendung der schnellstmöglichen Iterationsmethode.

Wir können sogar die WriteToConsole-Funktion so ändern, dass FastForEach verwendet wird

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

Der gesamte Quellcode, einschließlich einer Beispielverwendung von FastForEach, lautet nun:

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();
        }
    }
}

neue Liste { 1, 3, 5 }.ForEach(Console.WriteLine);

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

bearbeiten:Ahhh, er ist mir zuvorgekommen.

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

Bearbeiten:Teufel noch mal!Es hat zu lange gedauert, Visual Studio zum Testen zu öffnen.

Sie können auch beitreten:

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();
}

Dann später...

list.WriteLine();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top