2016-06-26 5 views
0

Ich habe eine Liste von Objekten, die eine Zeichenfolge enthalten, OR eine Liste von Zeichenfolgen. Ich versuche eine Liste von "abgeflachten" Strings zu extrahieren. Ich habe eine Lösung, aber ich versuche einen besseren Weg zu finden.Linq zum bedingten Abflachen einer Liste von Strings mit unterschiedlicher Tiefe

Hier sind die einfachen Schritte, um die Eingabe zu erstellen:

class Foo 
{ 
    public bool IsArray { get; set; } 
    public object Values { get; set; } 
} //...  

var innerList = new List<string> {"Inner111", "Inner222"} 

var fooList = new List<Foo>(); 
fooList.Add(new Foo { IsArray = false, Values = "simpleVaue" }); 
fooList.Add(new Foo { IsArray = false, Values = innerList }); 

Mein gewünschte Ergebnis:

["simpleVale","Inner111","Inner222"] 

ich ein paar verschiedene Linq Methoden, Select, Aggregate, Select versucht haben. ..

var outputListWithWastefulListCreation = 
fooList.SelectMany<Foo, string>(z => 
{ 
    if (!z.IsArray) 
    { 
     var wastefulList = new List<string> {z.Values.ToString()}; 
     return wastefulList; 
    } 
    var listObject = (IEnumerable<string>) z.Values; 
    return listObject; 
}); 

Wieder mein gewünschtes Ergebnis:

["simpleVale","Inner111","Inner222"] 

Ich bin sicher, es muss ein besserer Weg geben?

Antwort

0

können Sie versuchen, Einzelwert in eine Sammlung innerhalb SelectMany Umwandlung:

var result = fooList 
    .SelectMany(item => item.IsArray 
     ? item.Values as List<String> 
     : new List<String>() {item.Values as String}); 

Eine andere, und, meiner Meinung nach, eine bessere Möglichkeit IEnumerable<String> GetValues()' method in the foo` Klasse zu implementieren ist:

class Foo 
{ 
    public bool IsArray { get; set; } 
    public object Values { get; set; } 

    public IEnumerable<String> GetValues() 
    { 
     if (null == values) 
      yield break; 

     List<String> list = Values as List<String>; 

     if (list != null) 
      foreach (var item in list) 
       yield return item; 
     else 
      yield return Values as String; 
    } 
} 

und so Sie können nur setzen

var result = fooList 
    .SelectMany(item => item.GetValues()); 
0

Versuchen Sie folgende:

fooList.SelectMany<Foo, string>(z => z.IsArray ? ((List<string>) z.Values) : new List<string>() {(string) z.Values}); 

Aber das erste, was zu tun - ist zu überlegen, ob Ihre Foo Klasse Design ist ok, oder Sie können es ändern (mit wahrscheinlich zwei verschiedenen Klassen für eine Saite und die Liste) so knifflig Probleme zu vermeiden .

Verwandte Themen