2017-06-09 4 views
-2

Vor kurzem sah ich diesen Code von @edplunkett und dachte, das in etwas nützlich sein, würde ich aber tue ich Vertiefung aufzunehmen ändern mag:Was muss ich tun, um den Einzug zu ändern?

static void Main() 
{ 
var randomCrap = new List<Object> 
{ 
    1, "two", 
    new List<object> { 3, 4 }, 
    5, 6, 
    new List<object> { 
     new List<object> { 7, 8, "nine" }, 
    }, 
}; 

randomCrap.PrintAll(); 
} 

public static class Extensions 
{ 
    public static void PrintAll(this Object root) 
    { 
     foreach (var x in root.SelectAll()) 
     { 
      Console.WriteLine(x); 
     } 
    } 

    public static IEnumerable<Object> SelectAll(this object o) 
    { 
     // Thank you, eocron 
     if (o is String) 
     { 
      yield return o; 
     } 
     else if (o is IEnumerable) 
     { 
      var e = o as IEnumerable; 
      foreach (var child in e) 
      { 
       foreach (var child2 in child.SelectAll()) 
        yield return child2; 
      } 
     } 
     else 
     { 
      yield return o; 
     } 
    } 
} 

Wie einfach ist es jedes Mal hinzufügen Vertiefung eines IEnumerable angetroffen wird, so dass Sie diese bekommen würde:

1 
two 
    3 
    4 
5 
6 
    7 
    8 
    nine 

so etwas wie ein Start-Einzug von 0, die jeder IEnumerable begegnet durch eine erhöht?

+0

Hahaha! 'randomCrap'. Ich weiß, woher das kommt. – itsme86

Antwort

0

Sie können es ziemlich leicht mit Tupeln:

public static class Extensions 
{ 
    public static void PrintAll(this Object root) 
    { 
     foreach (var x in root.SelectAll("")) 
     { 
      Console.WriteLine(x.Item1 + x.Item2); 
     } 
    } 

    public static IEnumerable<(string, Object)> SelectAll(this object o, string indentation) 
    { 
     // Thank you, eocron 
     if (o is String) 
     { 
      yield return (indentation, o); 
     } 
     else if (o is IEnumerable) 
     { 
      var e = o as IEnumerable; 
      foreach (var child in e) 
      { 
       foreach (var child2 in child.SelectAll(indentation + " ")) 
        yield return (child2.Item1, child2.Item2); 
      } 
     } 
     else 
     { 
      yield return (indentation, o); 
     } 
    } 
} 

EDIT: Hier ist ein Pre-C# 7 Version (ungetestet, sollte aber funktionieren):

public static class Extensions 
{ 
    public static void PrintAll(this Object root) 
    { 
     foreach (var x in root.SelectAll("")) 
     { 
      Console.WriteLine(x.Item1 + x.Item2); 
     } 
    } 

    public static IEnumerable<Tuple<string, Object>> SelectAll(this object o, string indentation) 
    { 
     // Thank you, eocron 
     if (o is String) 
     { 
      yield return Tuple.Create(indentation, o); 
     } 
     else if (o is IEnumerable) 
     { 
      var e = o as IEnumerable; 
      foreach (var child in e) 
      { 
       foreach (var child2 in child.SelectAll(indentation + " ")) 
        yield return Tuple.Create(child2.Item1, child2.Item2); 
      } 
     } 
     else 
     { 
      yield return Tuple.Create(indentation, o); 
     } 
    } 
} 
+0

Hmm ... Wir kamen fast zur gleichen Zeit zum selben Schluss ... –

+0

@JamesCurran Ja. Eine etwas andere Implementierung, aber die gleiche Idee. – itsme86

+0

@ itsme86 danke dafür, aber ich kann das nicht zur Arbeit bringen. Wenn ich kopiere und einfüge, bekomme ich Fehler wie "Methode muss einen Rückgabetyp haben" im 'SelectAll' Schlüsselwort in der Zeile' public static IEnumerable <(string, Object)> SelectAll (dieses Objekt o, string indentation) '. Ich bekomme auch 'Syntaxfehler => erwartet' nach Zeile 'yield return (indentation, o);'. Sie scheinen es funktioniert zu haben, so dass mir etwas offensichtlich fehlt? – Monika

0

Das wäre eine ziemlich große Veränderung. Gerade jetzt geht es an die Funktion und kehrt von ihr einzelne Objekte zurück. Sie müssten dies ändern, um zwei Dinge zu übergeben und zurückzugeben: das Objekt und die Einzugsebene. Es könnte getan werden, aber es würde die Eleganz von @ edplunketts Design zerstören.

UPDATE: Eigentlich mit Tupeln, dann ist es nicht so schlimm, nachdem alle ::

static void Main() 
{ 
    var randomCrap = new List<Object> 
{ 
    1, "two", 
    new List<object> { 3, 4 }, 
    5, 6, 
    new List<object> { 
     new List<object> { 7, 8, "nine" }, 
    }, 
}; 

    randomCrap.PrintAll(); 
} 

public static class Extensions 
{ 
    public static void PrintAll(this Object root) 
    { 
     foreach (var x in root.SelectAll(0)) 
     { 
      Console.WriteLine("{0}{1}", new string('_', x.indent),x.obj); 
     } 
    } 

    public static IEnumerable<(Object obj,int indent)> 
        SelectAll(this object o, int indent) 
    { 
     // Thank you, eocron 
     if (o is String) 
     { 
      yield return (o,indent); 
     } 
     else if (o is IEnumerable) 
     { 
      var e = o as IEnumerable; 
      foreach (var child in e) 
      { 
       foreach (var child2 in child.SelectAll(indent+1)) 
        yield return child2; 
      } 
     } 
     else 
     { 
      yield return (o, indent); 
     } 
    } 
} 
Verwandte Themen