質問が移動しましたhere。Diffツールに似たクラスオブジェクトの2つのリストを比較する
私の要件は、模倣のdiffツールのようなプログラムを書くことです。はい、この目的を達成するライブラリとオープンソース・コードがかなりありますが、私は自分自身のcomparerを作成したいと思います。
ここが出発点です。私はこのようになりますのDataItemというクラスがあります。私は、これらのクラスオブジェクトの二つのリストを持っている
public class DataItem
{
public DataItem() { }
public DataItem(string d, string v) { Data = d; Value = v; }
public string Data { get; set; }
public string Value { get; set; }
}
を、のは、PREとPOSTそれらを呼び出すと、次のようにいくつかの例の値を取りましょう。 'データ'部分はリスト内で一意になります。
preList: (Data,Value)
AAA,0
BBB,1
CCC,3
DDD,4
FFF,0
GGG,3
postList: (Data,Value)
AAA,0
BBB,2
DDD,4
EEE,9
FFF,3
PREを元のリストと考え、いくつかの変更を行った後にPOSTとします。私は2つを比較し、3つのカテゴリに分類したいと思います:
- 追加された項目 - 新しい「データ」がリストに追加された項目。
- 削除されたアイテム - アイテムがリストから削除されました。
- 差分項目 - 「データ」はPREリストとPOSTリストの両方にありますが、対応する「値」は異なります。分類時に
そこで、彼らは次のようになります。
Added Items:
EEE,9
Removed Items:
CCC,3
GGG,3
Diff Items:
BBB
FFF
は私が最終的な結果を入れたいそれらのオブジェクトに、別のDiffItemクラスを持っています。 DiffItemは次のようになります。
public class DiffItem
{
public DiffItem() { }
public DiffItem(string data, string type, string pre, string post) { Data = data; DiffType = type; PreVal = pre; PostVal = post; }
public string Data { get; set; }
public string DiffType { get; set; } // DiffType = Add/Remove/Diff
public string PreVal { get; set; } // preList value corresponding to Data item
public string PostVal { get; set; } // postList value corresponding to Data item
}
は、これを達成するために、最初に私がされたIEqualityComparerを拡張し、する比較器のカップルを書いた:その後除き使用
public class DataItemComparer : IEqualityComparer<DataItem>
{
public bool Equals(DataItem x, DataItem y)
{
return (string.Equals(x.Data, y.Data) && string.Equals(x.Value, y.Value));
}
public int GetHashCode(DataItem obj)
{
return obj.Data.GetHashCode();
}
}
public class DataItemDataComparer : IEqualityComparer<DataItem>
{
public bool Equals(DataItem x, DataItem y)
{
return string.Equals(x.Data, y.Data);
}
public int GetHashCode(DataItem obj)
{
return obj.Data.GetHashCode();
}
}
()と交差()メソッドを次のように
static void DoDiff()
{
diffList = new List<DiffItem>();
IEnumerable<DataItem> preOnly = preList.Except(postList, new DataItemComparer());
IEnumerable<DataItem> postOnly = postList.Except(preList, new DataItemComparer());
IEnumerable<DataItem> common = postList.Intersect(preList, new DataItemComparer());
IEnumerable<DataItem> added = postOnly.Except(preOnly, new DataItemDataComparer());
IEnumerable<DataItem> removed = preOnly.Except(postOnly, new DataItemDataComparer());
IEnumerable<DataItem> diffPre = preOnly.Intersect(postOnly, new DataItemDataComparer());
IEnumerable<DataItem> diffPost = postOnly.Intersect(preOnly, new DataItemDataComparer());
foreach (DataItem add in added)
{
diffList.Add(new DiffItem(add.Data, "Add", null, add.Value));
}
foreach (DataItem rem in removed)
{
diffList.Add(new DiffItem(rem.Data, "Remove", rem.Value, null));
}
foreach (DataItem pre in diffPre)
{
DataItem post = diffPost.First(x => x.Data == pre.Data);
diffList.Add(new DiffItem(pre.Data, "Diff", pre.Value, post.Value));
}
}
これは機能し、ジョブが完了します。しかし、これを行うための「より良い」方法があるのだろうかと思っています。私はこれをより良くするための適切な定義を持っていないので、私は単語の周りに引用符を置くことに注意してください。おそらく、Linqの背後にはかなりの反復があると想像しているので、多くの 'foreach'ループとExcept()とIntersetc()の使用なしでこれを行う方法があります。
簡単に言えば、私はこれを書くことができるクリーナーコードがありますか?私は主に学問的な興味から欲しいと思っています。
これは、より良い[コードレビュー](https://codereview.stackexchange.com/)に掲載されます。 – hatchet
提案をありがとう!これをそこに移動することは可能でしょうか、削除してそこに投稿する必要がありますか? – Sach
私はコードレビューサイトに移動したので、この質問をトピックとしてクローズすることにしました。 – Sach