2 Stimmen

Gibt es eine Möglichkeit, bestimmte Elemente aus einer List<T> mit LINQ zu entfernen?

Ich habe eine Liste von Objekten, die geordnet sind. Ich möchte überflüssige Objekte entfernen, wobei überflüssig nicht unbedingt doppelt bedeutet. Hier ist ein Beispiel:

List<Point> points = new List<Point>
{
   new Point(0, 10),
   new Point(1, 12),
   new Point(2, 16),
   new Point(3, 16),
   new Point(4, 16),
   new Point(5, 13),
   new Point(6, 16),
};

Ich bin daran interessiert, die new Point(3, 16) Eintrag, weil er keine nützlichen Informationen liefert; ich weiß bereits, dass das Element bei 2=16 und das Element bei 4=16 ist. Die Information, dass 3=16 ist, nützt mir in meiner Anwendung nichts (denn ich habe bereits die Grenzen {2,4}=16), also möchte ich diesen Eintrag entfernen. Ich möchte auch nicht, dass ich den 5. und 6. Eintrag behalte, weil es keine aufeinanderfolgenden Einträge gibt, bei denen Y=16 ist.

Gibt es eine glatte Möglichkeit, dies mit Linq zu tun?

1voto

Tim Schmelter Punkte 427304

Editar : Dies führt zu dem erwarteten Ergebnis. Ich gruppiere eine List<Point> (bestellt von Point.X ) durch Point.Y . Dann nehme ich die erste und letzte Point in jeder Gruppe:

var result = points.OrderBy(p => p.X)
            .GroupBy(p => p.Y)
            .Select(grp =>
                grp.Where((p, index) => index == 0 || index == grp.Count() - 1))
                .SelectMany(p => p).OrderBy(p => p.X)
            .ToList();

1voto

Martin Bartoš Punkte 26

Und was ist damit?

public void Test()
{
 List<Point> points = new List<Point>
 {
  new Point(0, 10),
  new Point(1, 12),
  new Point(2, 16),
  new Point(3, 16),
  new Point(4, 16),
  new Point(5, 13),
  new Point(6, 16),
 };
 var subSetOfPoints = points.Where(p=> !IsInTheMiddleX(p, points));
}

private bool IsInTheMiddleX(Point point, IEnumerable<Point> points)
{
 return points.Any(p => p.X < point.X && p.Y == point.Y) && 
        points.Any(p => p.X > point.X && p.Y == point.Y);                        
}

0voto

ybakos Punkte 7320

Ich würde eine eigene Klasse definieren, die eine List<Point> so dass Sie Ihre eigene Logik implementieren können, indem Sie festlegen, was "redundant" ist oder andere Regeln, die Sie einhalten möchten. Dies scheint vernünftiger zu sein als die Verwendung von LINQ für diese Aufgabe.

0voto

Hier ist mein Versuch, es funktioniert gut, aber der Code muss besser sein:

 var distinctY = points.Select(p => p.Y).Distinct().ToList();

 List<Point> filtered = new List<Point>();
 foreach (var y in distinctY)
 {
     int minX, maxX;

     minX = points.Where(p => p.Y == y).Min(x => x.X);
     maxX = points.Where(p => p.Y == y).Max(x => x.X);

     filtered.Add(new Point(minX, y));

     if ( maxX != minX)      
        filtered.Add(new Point(maxX, y));
 }

0voto

Sandeep Punkte 6708

Wie der Name LINQ schon sagt, sollte es nur zur Abfrage von Daten verwendet werden.

Wenn ich Sie wäre, würde ich LINQ nicht zum Löschen oder Ändern der Liste verwenden. Ich verwende es nur, um sie abzufragen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X