2 つのバイナリ データ セットの違いを比較するソフトウェアを作成しています。バイナリ データには座標が含まれており、DBF ファイルから読み取って各オブジェクトの属性情報を取得します。私のソフトウェアは、オブジェクトが移動したかどうか、属性が変更されたかどうか、オブジェクトが削除/追加されたかどうかを示します。
カスタム オブジェクトのハッシュコードは、各インスタンス内の座標のリストに基づいて生成されます。各オブジェクトにはデータ行もあります。最初に「不完全なレコード」(基本的には、座標とデータ行に基づいて一致しないオブジェクト) を見つけようとすると、データ行が考慮され、データ行が十分に一意になるため、HashSet を使用できます。
public override int GetHashCode()
{
if (considerAttrs)
{
return (value.GetHashCode() + dbString.GetHashCode());
}
else
{
return value.GetHashCode();
}
}
わたしはどこにいますか:
現時点では、ソフトウェアは完全に一致しない (座標と属性が完全に一致しない) オブジェクトを返します。このデータは正しいです (少なくとも私は願っています)
origUnfoundCount: 114 modUnfoundCount: 223
113 の属性が変更され、1 が移動されたため、元の 114 は見つかりません。113 の変更された属性があり、1 が移動され、109 が追加されたため、変更された属性で 223 を見つけることができません。
私が立ち往生している場所:
このソフトウェアは、小さなデータ (各リストで数百) を美しく処理します。
各オブジェクトの thinkAttrs を false に変更し、HashSet の代わりに List を使用しました。私のアプリケーションの点では、データ間の小さな違いを比較するのにしか適していません。
ただし、ハッシュセットに重複を含めることはできないため、リストを使用する必要がありますが、リストは遅くなるだけです。キーは一意でなければならないため、辞書は使用できません
私は新しいアプローチが必要です。以下の私のロジックは、私がそれを行うために必要なことの一般的な要点を提供するはずです.
私の現在の比較コード
//ignored modified records
HashSet<int> ignoredRecNo = new HashSet<int>();
//ignoring moved records
HashSet<String> ignoredDBstrings = new HashSet<string>();
HashSet<String> columnNames = new HashSet<string>();
HashSet<int> modModdedRNs = new HashSet<int>();
columnNames = (HashSet<String>)HttpContext.Current.Session["columnNames"];
List<PolyLineZ> originalNFs = new List<PolyLineZ>();
List<PolyLineZ> modifiedNFs = new List<PolyLineZ>();
List<PolyLineZ> removedList = new List<PolyLineZ>();
List<PolyLineZ> movedList = new List<PolyLineZ>();
List<PolyLineZ> modifiedList = new List<PolyLineZ>();
List<PolyLineZ> modifiedMatchList = new List<PolyLineZ>();
List<PolyLineZ> movedOrDeleted = new List<PolyLineZ>();
if (HttpContext.Current.Session["origNFList"] != null)
{
origPolyLineZNFList = (HashSet<PolyLineZ>)HttpContext.Current.Session["origNFList"];
}
if (HttpContext.Current.Session["modNFList"] != null)
{
modPolyLineZNFList = (HashSet<PolyLineZ>)HttpContext.Current.Session["modNFList"];
}
//----------Generate Lists of string for each row---------------//
foreach (PolyLineZ polyLineZ in origPolyLineZNFList)
{
origDBStrings.Add(polyLineZ.dbString);
PolyLineZ temp = new PolyLineZ();
temp = polyLineZ;
temp.considerAttrs = false;
originalNFs.Add(temp);
}
foreach (PolyLineZ polyLineZ in modPolyLineZNFList)
{
modDBStrings.Add(polyLineZ.dbString);
PolyLineZ temp = new PolyLineZ();
temp = polyLineZ;
temp.considerAttrs = false;
modifiedNFs.Add(temp);
}
foreach (PolyLineZ modpolyLineZ in modifiedNFs)
{
bool foundAmatch = false;
foreach (PolyLineZ origPolyLineZ in originalNFs)
{
if (origPolyLineZ.Equals(modpolyLineZ))
{
if (!modDBStrings.Contains(origPolyLineZ.dbString))
{
//database modifications are in here
modModdedRNs.Add(origPolyLineZ.RecordNumber);
foundAmatch = true;
break;
}
}
}
}
foreach (PolyLineZ polyLineZ in originalNFs)
{
bool foundAmatch = false;
foreach (PolyLineZ modpolyLineZ in modifiedNFs)
{
if (foundAmatch)
{
break;
}
if (modpolyLineZ.Equals(polyLineZ))
{
if (!origDBStrings.Contains(modpolyLineZ.dbString))
{
foundAmatch = true;
//database modifications are in here
ignoredRecNo.Add(modpolyLineZ.RecordNumber);
ignoredDBstrings.Add(modpolyLineZ.dbString);
modifiedList.Add(polyLineZ);
modifiedMatchList.Add(modpolyLineZ);
break;
} // end db string comparison
} //end shape equals if
} //end modNF loop
if (!foundAmatch)
{
movedOrDeleted.Add(polyLineZ);
ignoredDBstrings.Add(polyLineZ.dbString);
ignoredRecNo.Add(polyLineZ.RecordNumber);
}
} //end origNF loop
result += "movedDeletedCount: " + movedOrDeleted.Count + "<br/>";
foreach (PolyLineZ polylineZ in movedOrDeleted)
{
if (!modDBStrings.Contains(polylineZ.dbString))
{
removedList.Add(polylineZ);
}
else
{
movedList.Add(polylineZ);
}
}
/*************************** ITERATE DATABASE CHANGES***********************************/
for(int i=0; i < modifiedList.Count;i++)
{
if (modModdedRNs.Contains(modifiedList[i].RecordNumber))
{
if (modifiedAttrs < 1001)
{
//database modifications are in here
ignoredRecNo.Add(modifiedMatchList[i].RecordNumber);
ignoredDBstrings.Add(modifiedMatchList[i].dbString);
modifiedAttrs++;
modifiedResults += "<div class='turnBlue'>";
//show where the change was made at
modifiedResults += "Change Detected at original FID# " + (modifiedList[i].RecordNumber - 1) + " and modified FID#";
HashSet<String> mismatchedColumns = new HashSet<String>();
modifiedResults += (modifiedMatchList[i].RecordNumber - 1);
modifiedResults += "</div>"; //end turnblue div
DataRow origRow = modifiedList[i].datarow;
DataRow modRow = modifiedMatchList[i].datarow;
foreach (String columnName in columnNames)
{
String origRowValue = "" + origRow.Field<Object>(columnName);
String modRowValue = "" + modRow.Field<Object>(columnName);
if (!modRowValue.Equals(origRowValue))
{
mismatchedColumns.Add(columnName);
}
}
foreach (String mismatchedColumn in mismatchedColumns)
{
//grab original attr value
String origMismatchedRowValue = "" + origRow.Field<Object>(mismatchedColumn);
//grab the modified value
String modMismatchedRowValue = "" + modRow.Field<Object>(mismatchedColumn);
//generate a heading, letting the user know about the situation
modifiedResults += "<div class='turnBlue'>Value at Column: <b>" + mismatchedColumn + "</b> has been modified<br/>";
modifiedResults += "<div class='pushLeft'>Original value: <b>" + origMismatchedRowValue + "</b><br/></div>";
modifiedResults += "<div class='pushLeft'>Modified value: <b>" + modMismatchedRowValue + "</b><br/></div>";
modifiedResults += "</div>"; //end modified div
}
}
else
{
modifiedAttrs++;
}
}
else
{
if (removed < 1001)
{
//iterate removed data here
removed++;
}
else
{
removed++;
}
}
}
//****************************this determines which ones have been added ***************************/
foreach (PolyLineZ modpolyLineZ in modifiedNFs)
{
if (!ignoredRecNo.Contains(modpolyLineZ.RecordNumber) && (!ignoredDBstrings.Contains(modpolyLineZ.dbString)))
{
//iterate added data here
}
}
foreach (PolyLineZ polylineZ in removedList)
{
//iterate removed data here
}
foreach (PolyLineZ polylineZ in movedList)
{
//iterate moved data here
}
result += "<div id='addedJump'></div>" + addedResult;
result += "<div id='moddedJump'></div>" + modifiedResults;
result += "<div id='removedJump'></div>" + removedResults;
result += "<div id='movedJump'></div>" + movedResults;
}