2016-08-29 13 views
1
Mylist.GroupBy(x => new{x.X, x.Y}).Select(g => g.First()).ToList<XYZ>(); 

上記のコードは私にとってうまく機能します。私はポイントコンポーネントのラウンド(5)に基づいてポイントを比較したいだけです。XYZポイントのリストで重複を削除してください

たとえば、x.X = 16.838974347323224は、ラウンド5の後にいくつかの不正確さがあったため、x.X = 16.83897としか比較されません。

ソリューション:

Mylist.GroupBy(x => new { X = Math.Round(x.X,5), Y = Math.Round(x.Y,5) }) 
       .Select(g => g.First()).ToList(); 
+1

問題はかなり真っ直ぐに思えます。何を試してみましたか、どこに問題がありますか? –

+0

対応する丸めを 'new {x.X、...} 'に追加するだけです。 – CSharpie

+0

2つの点の3つの成分x、y、zが通常同じである重複が削除されました。しかし、たとえばx = 1.1111111111109とx = 1.1111111111108の場合、2つの点が残っているので、上記の同じ文で丸め条件を追加できるかどうかを尋ねています! –

答えて

0

はとても使いくださいするにはMath.Round

var result = Mylist.GroupBy(x => new { X = Math.Round(x.X,5, MidpointRounding.AwayFromZero), Y = Math.Round(x.Y,5, MidpointRounding.AwayFromZero) }) 
        .Select(g => g.First()).ToList(); 

しかしその後、重複を削除することで何がしたいの代わりにGroupByのこれらのいずれかのために行く場合:

  1. Selectは丸められ、その後Distinct

    public class RoundedXyzComparer : IEqualityComparer<XYZ> 
    { 
        public int RoundingDigits { get; set; } 
        public RoundedXyzComparer(int roundingDigits) 
        { 
         RoundingDigits = roundingDigits; 
        } 
    
        public bool Equals(XYZ x, XYZ y) 
        { 
         return Math.Round(x.X, RoundingDigits, MidpointRounding.AwayFromZero) == Math.Round(y.X, RoundingDigits, MidpointRounding.AwayFromZero) && 
           Math.Round(x.Y,RoundingDigits, MidpointRounding.AwayFromZero) == Math.Round(y.Y, RoundingDigits, MidpointRounding.AwayFromZero); 
        } 
    
        public int GetHashCode(XYZ obj) 
        { 
         return Math.Round(obj.X, RoundingDigits, MidpointRounding.AwayFromZero).GetHashCode()^
           Math.Round(obj.Y, RoundingDigits, MidpointRounding.AwayFromZero).GetHashCode(); 
        } 
    } 
    
    //Use: 
    myList.Distinct(new RoundedXyzComparer(5)); 
    
  2. var result = Mylist.Select(item => new XYZ { X = Math.Round(item.X,5, MidpointRounding.AwayFromZero), 
                  Y = Math.Round(item.Y,5, MidpointRounding.AwayFromZero)}) 
            .Distinct().ToList(); 
    
  3. DistinctEqualsGetHashCodeをオーバーライドするには -

  4. Distinctを提案し、カスタムIEqualityComparerを実装していないだろう - (丸め等号が行います)

+0

最初は区別していませんでしたが、Comparerを少し混乱させてしまい、list.Extinct(comparer).tolist()にエラーが発生しました。 –

+0

@IbrahemHamdyNaeem - 最初と最後のオプションをチェックしました彼らの仕事: –

+0

はい私は更新として最初の1つ解決しました!私はこのサイトを愛するようになります、それは素晴らしいです。 –

4

Roundは、2つの数字が非常に近いものの、別々のものとみなされる可能性がある状況を作り出すことができます。

は、この例を見てみましょう:

var Mylist = new [] 
{ 
    new { X = 1.0000051, Y = 1.0 }, 
    new { X = 1.0000049, Y = 1.0 }, 
    new { X = 1.1, Y = 1.0 }, 
    new { X = 1.0, Y = 1.005 }, 
}; 

最初の2つの値が非常に接近している - 実際に、彼らは第六小数点以下が異なります。

var result = 
    Mylist 
     .GroupBy(x => new 
     { 
      X = Math.Round(x.X,5, MidpointRounding.AwayFromZero), 
      Y = Math.Round(x.Y,5, MidpointRounding.AwayFromZero) 
     }) 
     .Select(g => g.First()) 
     .ToList(); 

結果は次のとおりです:

result1

丸めはこれらの2つの値を保持することを可能にした私たちは、このコードを実行した場合どのようなことで

正しいアプローチは距離でフィルタリングすることです。後続の値が以前の値のしきい値内にある場合は、それを破棄する必要があります。

ここことを行うコードです:

result2

これは、重複を除去するために、より良い最適です:我々はこれを取得Mylistデータにすることを実行した場合今

var threshold = 0.000001; 
Func<double, double, double, double, double> distance 
    = (x0, y0, x1, y1) => 
     Math.Sqrt(Math.Pow(x1 - x0, 2.0) + Math.Pow(y1 - y0, 2.0)); 

var result = Mylist.Skip(1).Aggregate(Mylist.Take(1).ToList(), (xys, xy) => 
{ 
    if (xys.All(xy2 => distance(xy.X, xy.Y, xy2.X, xy2.Y) >= threshold)) 
    { 
     xys.Add(xy); 
    } 
    return xys; 
}); 

が。

+0

cool :)私はこれが好きです。 (そして、私が示唆したことは 'GroupBy'ではなく、 'Distinct'です –

+0

これは実際に私が学ばなければならなかった良い点です。この明確化のための@Enigmativity、私は不要な中間の余分ポイント!それを実装するとき、私はここに書き戻します。 –

関連する問題