2015-12-08 11 views
9

ich aus der Datenbank Sytem.Collections.generic.IList und filtern sie durch searchText:Sortieren in Liste Objekt

String searchText="E"; 
var query = something().List(); 
query = query.Where(x => !string.IsNullOrEmpty(x.Name) && 
x.Name.ContainsInsensitive(searchText)).ToList(); 
result = query.Select().ToList(); 

Nun möchte ich dieses Ergebnis durch Name Spalte sortiert ist. Zuerst alle Werte, beginnend mit searchText und dann alle Werte, die searchText enthalten.

Wenn ich dies schreibe:

result = result.OrderBy(x => x.Name).ToList(); 

I Ergebnis nach Namen sortiert bekommen, zum Beispiel:

1. "A name"  
2. "B name" 
3. "E name" 
4. "F name" 

Das alles enthält e in Name. Ich möchte, dass meine Art ist:

1. "E name"  
2. "A name" 
3. "B name" 
4. "F name" 

Was soll ich in meinem OrderBy Ausdruck ändern?

+1

Ich glaube nicht, dass das standardmäßig möglich ist. Sortierung nach String funktioniert anders –

+6

@AmitKumarGhosh - sehr wenig ist "standardmäßig" möglich. Hier kommt das Programmierbit;) – Jamiec

+0

Ich habe den Abschnitt 'searchText' übersprungen. Ja. wahr. –

Antwort

13

Kette zusammen 2 Aufträge mit OrderBy und ThenBy

.OrderBy(x => x.Name.StartsWith(searchText) ? 0 : 1) 
.ThenBy(x => x.Name) 
+0

Danke. Es klappt. – Simon

10

Sie können nach dem anderen zwei Sortier Anrufe (Erste OrderBy, alle nachfolgenden ThenBy):

result.OrderBy(x => !x.Name.StartsWith(searchText)).ThenBy(x => x.Name).ToList(); 

Dies wird sortieren true (1) zuerst, dann (0) falsch. Die !x.Name macht die Bestellung richtig. Dann sortiert es in beiden Gruppen x.Name.

1

Ich denke, dies ist genauer:

result.OrderByDescending(x=>Regex.Split(x.Name, searchText, RegexOptions.IgnoreCase).Count()).ToList(); 

Oder noch besser:

result.OrderByDescending(x => 
    Regex.Split(x.Name, searchText, RegexOptions.IgnoreCase) 
    .Sum(el => el.StartsWith(searchText, StringComparison.InvariantCultureIgnoreCase) ? 1 : 0) 
).ToList(); 
+0

Warum denkst du das? –

+0

Zählt, wie oft der searchText im Namen – csharpwinphonexaml

+0

vorhanden ist. Warum ist er genauer? Wo prüft es "beginnt mit", wie von OP gefragt? –

3

Nun, nach Ihrem Code Sie haben resultmaterialisiert als List<T>:

result = query.Select().ToList(); 

Und dann bist du Neue und Neuzuweisung die Liste:

result = result.OrderBy(x => x.Name).ToList(); 

Deshalb schlage ich vor in-place statt OrderBy Sortierung:

result.Sort((x, y) => { 
    if (x.Name.StartsWith(searchText)) { 
     if (!y.Name.StartsWith(searchText)) 
     return 1; 
    } 
    else if (y.Name.StartsWith(searchText)) 
     return -1; 

    return String.Compare(x.Name, y.Name); 
    }); 
2

Ich denke, was Sie wichtig ist der Index der Suchzeichenfolge ist. Also würde die Zeichenfolge, die früher searchText entspricht, zuerst werden. hier ist Beispiel:

String searchText = "E"; 
List<string> result = new List<string> 
{ 
    "B name", 
    "A name", 
    "E name", 
    "FE name", 
}; 


result = result.OrderBy(x => x.IndexOf(searchText, StringComparison.OrdinalIgnoreCase)).ThenBy(x=>x).ToList(); 

Sie

"E name", 
"FE name", 
"A name", 
"B name", 

bekommen Aber wenn ihr nicht, was Sie dann StartsWith verwenden sucht wie in anderen Antworten.

+2

Das ist ein netter Ansatz, an den ich noch nicht gedacht habe. Das Problem ist, dass es den Rest nicht wie erwartet sortiert, da 'A' jetzt nach' FE' sortiert wird. –

+0

@PatrickHofman sortiert zuerst nach 'searchText'. 'Ein Name' hat' e' an der letzten Position, aber 'FE name' hat' e' an der zweiten Position, so dass es vor 'A name' steht. –

+0

Ich weiß, aber das ist vielleicht nicht das, was OP erwartet. –