2016-01-26 4 views
7

Ich habe ein Array von MyClass, die wie folgt vereinfacht werden können:LINQ Lösung für mehr Behebt

public class MyClass { 
    public int Id; 
    public string Origin; 
    public int Points; 
    public DateTime RequestTime; 
    public MyClass(int id, string origin, int points, DateTime requestTime) { 
     Id = id; 
     Origin = origin; 
     Points = points; 
     RequestTime = requestTime; 
    } 
} 

Jetzt, in den Array, ohne Fehler von der Benutzerseite oder während des Eingabeprozesses, es kann nicht sei MyClass Instanz mit identischen Id und Origin.

Jedoch, wenn es irgendwelche gibt, sollte ich es auflösen. Und hier sind die Auflösungsregeln:

  1. Zum einen durch Points - das heißt, ein unter den Duplikaten zu nehmen, hat die höchste Points

  2. Aber wenn die Points gleich sind, muss ich weiter lösen Sie es mit RequestTime - die neueste wird genommen werden.

  3. Und wenn, gibt es keinen Unterschied in RequestTime, dann kann ich eines der Duplikate beliebig nehmen.

Hier ist die Daten Abtastwerteingang ich habe:

MyClass[] myarr = new MyClass[] { 
    new MyClass(1, "Ware House 1", 5, new DateTime(2016, 1, 26, 14, 0, 0)), //[0] 
    new MyClass(1, "Ware House 1", 7, new DateTime(2016, 1, 26, 14, 0, 0)), //[1] //higher points 
    new MyClass(1, "Ware House 2", 7, new DateTime(2016, 1, 26, 14, 0, 0)), //[2] 
    new MyClass(1, "Ware House 2", 7, new DateTime(2016, 1, 26, 14, 1, 0)), //[3] //later time 
    new MyClass(1, "Ware House 2", 7, new DateTime(2016, 1, 26, 14, 0, 0)), //[4] 
    new MyClass(2, "Ware House 2", 7, new DateTime(2016, 1, 26, 14, 0, 0)), //[5] //higher points 
    new MyClass(2, "Ware House 2", 5, new DateTime(2016, 1, 26, 14, 1, 0)), //[6] //later time but less points 
    new MyClass(3, "Ware House 1", 6, new DateTime(2016, 1, 26, 14, 0, 0)), //[7] //triplet, pick any 
    new MyClass(3, "Ware House 1", 6, new DateTime(2016, 1, 26, 14, 0, 0)), //[8] //triplet, pick any 
    new MyClass(3, "Ware House 1", 6, new DateTime(2016, 1, 26, 14, 0, 0)) //[9] //triplet, pick any 
}; 

Das Endergebnis sollte [1], [3], [5], + any of [7]/[8]/[9]

I LINQ Lösung für sie, aber stecken implementieren möchten. Ich weiß nicht, wie man es sofort abfragt.

Irgendeine Idee?

Antwort

8

Gruppe von {Id, Origin} und nehmen die erste aus jeder Gruppe wenn sie von Points und RequestTime bestellt:

var query = from x in myarr 
    group x by new {x.Id, x.Origin} 
    into g 
    select (
     from z in g 
     orderby z.Points descending, z.RequestTime descending 
     select z).First(); 

In Methode Syntax, ist dies:

var query = 
    myarr.GroupBy(x => new {x.Id, x.Origin}) 
     .Select(g => g.OrderByDescending(z => z.Points) 
         .ThenByDescending(z => z.RequestTime) 
         .First()); 
+0

Dies funktioniert! Vielen Dank! : D Ich werde es akzeptieren, sobald ich kann ... – Ian

+0

Ah, ich kann sehen, dass der Trick darin besteht, sowohl Id als auch Origin zu "gruppieren", bevor sie es zweimal hintereinander bestellen. Ich wusste vorher nicht, dass wir nach zwei Elementen gruppieren könnten. Ich dachte daran, Double 'GroupBy' zu machen, was wegen der Art des" Composite Key "nicht gut zu sein schien. Nochmals vielen Dank! :) – Ian

+1

@Ian Ja, anonyme Typen sind dein Freund in Gruppierung und Beitritt. –

0

Versuchen folgende:

myarr.OrderBy(m=> m.Points).ToList(); 

oder

myarr.OrderBy(m=> m.Points).Orderby(m=> m.RequestTime); 
+0

Danke für die prompte Antwort ... es zu bestellen allein ist nicht schwierig, aber wo ich stecken geblieben war, als ich versuchte, Duplikate auf die Lösung Regeln zu entfernen, basiert. Irgendeine Idee? – Ian

+0

dit Sie folgenden Beitrag sehen: http://StackOverflow.com/Questions/1606779/Remove-duplicates-in-the-list-using-linq –