2012-01-30 10 views
9

Mam ciąg oddzielonych kropką („”) znaków, który reprezentuje hierarchię:Podział oddzielone ciąg w hierarchii za pomocą C# i LINQ

string source = "Class1.StructA.StructB.StructC.FieldA"; 

Jak mogę używać C# i LINQ aby podzielić ciąg w oddzielnych ciągi, aby pokazać ich hierarchię? Takich jak:

string[] result = new string[] 
{ 
    "Class1", 
    "Class1.StructA", 
    "Class1.StructA.StructB", 
    "Class1.StructA.StructB.FieldA" 
}; 

Odpowiedz

12

Podziel ciąg znaków przez ograniczniki, biorąc 1 ... N różnych poziomów i ponownie dołącz łańcuch.

const char DELIMITER = '.'; 
var source = "Class1.StructA.StructB.StructC.FieldA"; 
var hierarchy = source.Split(DELIMITER); 
var result = Enumerable.Range(1, hierarchy.Length) 
    .Select(i => String.Join(".", hierarchy.Take(i))) 
    .ToArray(); 

Oto bardziej efektywny sposób to zrobić bez LINQ:

const char DELIMITER = '.'; 
var source = "Class1.StructA.StructB.StructC.FieldA"; 
var result = new List<string>(); 
for (int i = 0; i < source.Length; i++) 
{ 
    if (source[i] == DELIMITER) 
    { 
     result.Add(source.Substring(0, i)); 
    } 
} 
result.Add(source); // assuming there is no trailing delimiter 
+0

Eleganckie rozwiązanie –

+0

Doskonała odpowiedź. Rozwiązanie linq jest ważne, ponieważ będę czytać 100 z nich z xml i grupować je razem w automatycznie generowane klasy. – sean

0

Oto rozwiązanie, które wykorzystuje agregacji:

const string separator = "."; 
const string source = "Class1.StructA.StructB.StructC.FieldA"; 

// Get the components. 
string[] components = source.Split(new [] { separator }, StringSplitOptions.None); 

List<string> results = new List<string>(); 
// Aggregate with saving temporary results. 
string lastResult = components.Aggregate((total, next) => 
    { 
     results.Add(total); 
     return string.Join(separator, total, next); 
    }); 
results.Add(lastResult); 
0

Oto rozwiązanie całkowicie bez LINQ:

public static string[] GetHierarchy(this string path) 
{ 
    var res = path.Split('.'); 
    string last = null; 
    for (int i = 0; i < res.Length; ++i) 
    { 
     last = string.Format("{0}{1}{2}", last, last != null ? "." : null, res[i]); 
     res[i] = last; 
    } 
    return res; 
} 
0

Shlemiel malarz zatwierdza h jest lepszy niż łańcuch "super Shlemiel". Dołącz do tego przypadku.

 const char DELIMITER = '.'; 

     string soFar = ""; 
     List<string> result = source.Split(DELIMITER).Select(s => 
     { 
      if (soFar != "") { soFar += DELIMITER; }; 
      soFar += s; 
      return soFar; 
     }).ToList();