2016-09-06 86 views
3

我有一個列表包含一堆基於x和y位置的位置,我正在取兩個位置的區別。所以,例如我有像(0,1),(1,0)和(1,2),(2,1)和(2,3),(3,2)這樣的重複。我想從我的列表中刪除所有這些重複項目以實現我的目標。是否有捷徑可尋?我一直在試圖建立一個算法,但它很難。因爲我已經得到了像90點的位置,這是不容易確定,當它複製自身如何刪除c#列表中的重複項

+0

你想要刪除除了一個之外的所有東西嗎? –

+0

不,我想刪除相反的位置,因爲我正在改變它們,並且它們會給出相同的結果。因此,如果我有(0,1)和(1,0),我想刪除(1,0)。 @TimSchmelter –

+1

(1,0)和(0,1)是如何重複的? –

回答

2

我會用Enumerable.Distinct與邏輯的自定義comparerer:

public class OppositeLocationsEqualComparer : IEqualityComparer<Location> 
{ 
    public bool Equals(Location l1, Location l2) 
    { 
     if (object.ReferenceEquals(l1, l2)) return true; 
     if (l1 == null || l2 == null) return false; 
     return (l1.X == l2.X && l1.Y == l2.Y) || (l1.X == l2.Y && l1.Y == l2.X); 
    } 

    public int GetHashCode(Location l) 
    { 
     if(l == null) return int.MinValue; 
     return Math.Abs(l.X - l.Y); 
    } 
} 

現在你可以使用Enumerable.Distinct(和許多其他LINQ方法)與此比較器:

List<Location> uniqueLocations = locationList 
    .Distinct(new OppositeLocationsEqualComparer()) 
    .ToList(); 
7

最簡單的解決方案是爲您的點類IEqualityComparer不關心你X和的順序,然後您可以使用Distinct擺脫重複。

public class MyPoint 
{ 
    public int X { get; set; } 
    public int Y { get; set; } 
} 

public class PointComparer : IEqualityComparer<MyPoint> 
{ 
    public bool Equals(MyPoint x, MyPoint y) 
    { 
     if (ReferenceEquals(x, y)) return true; 
     if (ReferenceEquals(x, null)) return false; 
     if (ReferenceEquals(y, null)) return false; 
     return (x.X == y.X && x.Y == y.Y) || 
       (x.X == y.Y && x.Y == y.X); 
    } 

    public int GetHashCode(MyPoint obj) 
    { 
     return (obj?.X.GetHashCode() ?? 0)^(obj?.Y.GetHashCode() ?? 0); 
    } 
} 

class Program 
{ 
    static void Main() 
    { 
     List<MyPoint> data = GetDataFromSomewhere(); 

     var singularData = data.Distinct(new PointComparer()).ToList(); 
    } 
}