2012-04-06 14 views
2

Ich habe ein List<T> wo T mein Event Typ ist, der ein Feld longtime Typen hat. Diese Liste wird von einem Webdienst ausgefüllt und wenn ein Ereignis keine Zeit hat, ist der Wert 0.Individuelle Sortierung der Liste <T>

Was ich tun möchte, ist meine Liste aufsteigend nach Zeit sortieren, aber die Elemente mit Zeit = 0 ganz unten.

Momentan erreiche ich dies in einer Art von Hack und ich möchte einen besseren Weg lernen.

var events = new ObservableCollection<Event>(); 
var resp = JsonConvert.DeserializeObject<Events>(restResponse.Content).Items; 

var notime = resp.Where(r => r.time == 0); 
var yestime = resp.Where(r => r.time > 0); 

yestime.ToList().ForEach(events.Add); 
notime.ToList().ForEach(events.Add); 

CallbackInternal(callback, events); 

Ich versuchte IComparer eine benutzerdefinierte Implementierung, aber das so gut (hier ist ein Schuss auf ihn) hat nicht funktioniert

public class EventComparer : IComparer<Event> 
{ 
    public int Compare(Event x, Event y) 
    { 
     if (x.time == 0) return 0; 
     if (x.time < y.time) return -1; 
     if (x.time > y.time) return 1; 
     return 0; 
    } 
} 

Führung geschätzt wird!

danke!

Antwort

11

events.OrderBy (e => e.Time == 0).ThenBy (e => e.Time); 
+0

Dies ist die beste Lösung. Bools können auch sortiert werden! – usr

+0

+1 für Eleganz – phoog

+0

Ich mag es, wenn Dinge auf einfache Weise erledigt werden. +1 – rageit

1

Sie sollten etwas tun:

if(x.time==y.time) return 0; 
if(x.time==0) return 1; 
return x.time - y.time; 

Der Punkt hier ist, dass 0 größer als jede andere Zeit, so dass es dann am Ende der Liste gesetzt werden.

+0

danke, ich konnte einfach nicht klar zu denken, dass dies durch. Das hilft! – earthling

2

könnten Sie LINQ verwenden:

resp.OrderBy(i => i.time == 0 ? int.MaxValue : i.time); 
+0

Ich habe etwas in dieser Richtung versucht, aber ich habe meine Logik nicht richtig verstanden. Es scheint alles jetzt so klar :) – earthling

1

Ihre benutzerdefinierte IComparer falsch ist. Mit korrekter Logik sollte es gut funktionieren. Das Problem ist, dass, wenn der linke Wert Null ist, jeder Wert gleich ist. Dies bedeutet, dass 0 == 3 wahr ist und 3 > 0 wahr ist. In der Tat sollte 0 > 3 und 3 < 0 wahr sein

Sie sollten wie diese stattdessen etwas tun:

if (x.time == y.time) return 0; 
if (x.time == 0) return 1; 
if (y.time == 0) return -1; 
return x.time.CompareTo(y.time); 
1

Versuchen Sie dieses Versuchen (Sie haben für Ihre Bedürfnisse einstellen):

class Comparer : IComparer<int> 
    { 
     public int Compare(int x, int y) 
     { 
      if (x == y) return 0; 
      else if (x == 0) return 1; 
      else if (y == 0) return -1; 
      else if (x < y) return -1; 
      else if (x > y) return 1; 
     } 
    } 
+0

Dies ist gebrochen für '.Compare (0, 0)', die '0' zurückgeben sollte, aber '1' zurückgibt. – phoog

+0

Sie haben Recht. Das habe ich korrigiert. – Spook

+0

+1 ... aber Sie brauchen nicht 'else' nach' return' – phoog

Verwandte Themen