2017-01-05 8 views
3

IEqualityComparerを実装しようとしていますが、これは日付比較の許容差があります。私もthis questionを見てきました。問題は、LINQ .GroupJoin()IEqualityComparerを使用しているため、回避策を使用できないことです。私は公差を許容するいくつかの実装を試みました。私は両方のオブジェクトを持っているのでEquals()を得ることができますが、実装する方法を理解できませんGetHashCode()。それは両方の/すべてのオブジェクトに追加し日間適用されるGetHashCode()のうちHashTableを構築.GroupJoin()IEqualityComparer GetHashCodeを許容値で使用する

public class ThingWithDateComparer : IEqualityComparer<IThingWithDate> 
{ 
    private readonly int _daysToAdd; 

    public ThingWithDateComparer(int daysToAdd) 
    { 
     _daysToAdd = daysToAdd; 
    } 

    public int GetHashCode(IThingWithDate obj) 
    { 
     unchecked 
     { 
      var hash = 17; 
      hash = hash * 23 + obj.BirthDate.AddDays(_daysToAdd).GetHashCode(); 
      return hash; 
     } 
    } 

    public bool Equals(IThingWithDate x, IThingWithDate y) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public interface IThingWithDate 
{ 
    DateTime BirthDate { get; set; } 
} 

私の最高の試みは、次のようになります。これは機能しません。

+0

daysToは1日の許容値内で1月5日が1月6日と同じように許容範囲を追加しますか?この等価性の定義は推移的ではないので、すべてのオブジェクトに対して同じハッシュコードを返す簡単な解決策の外で、IEqualityComparerを使用して正しく実装することは可能であるとは思わない。 –

+0

それを忘れてしまった。 'GroupJoin'を' SelectMany'と単純な 'Where'で置き換えます(それほどパフォーマンスは良くないが動作するはずです)。 –

+0

@mikezはい、それは公差です。名前はちょうど悪いです。私がこの作業をすることができなければ、 'GroupJoin()'のカスタム版を実装するだけです。 –

答えて

2

問題は概念的に不可能です。あなたは、あなたがそれを使って実行しようとしている操作に必要な平等の形を持たない方法でオブジェクトを比較しようとしています。たとえば、GroupJoinは、AがBに等しく、BがCに等しい場合、AはCに等しいと仮定していますが、状況によってはそうではありません。 AとBは、グループ化したいと思うほど「十分に近い」かもしれませんが、AとCは同じではありません。

IEqualityComparerを実装する必要はありません。必要な契約を履行できないためです。 1つのコレクション内のアイテムのマッピングを、別のコレクション内のすべてのアイテムに作成したい場合は、そのアルゴリズムを「十分に近い」ものにする必要があります(そのように効率的に行うことは、非効率的に実行することは、その操作を実行できないため、GroupJoinを使用するのではなく、難しくはありません。

+0

これは正解と思われます。その答えは答えがないことが残念です。 –

1

指定された条件に論理ハッシュコードを生成する方法はありません。
ハッシュコードは、2つの日付が重なっているかどうかを判断するために使用されます。グループ化する必要がある場合は、同じハッシュコードを返す必要があります。

"float"が5日の場合、1/1/2000は1/4/2000と同じハッシュコードを生成する必要があり、1/4/2000は1/8/2000年(両者はお互いに5日以内であるため)。これは、2000年1月1日が2000年1月8日と同じコードを持つことを意味します(a = bとb = c、a = cなので)。

1/1/2000および1/8/2000は、5日間の "float"外です。

+0

非常に真です。私は 'GroupJoin'の使用を廃止し、左側からシードを持つ' Comparer'を可能にするバージョンを実装しなければならないと思っています。 –

関連する問題