私は、既存のコード ベースに機能を追加する任務を負っています。コードは主に、私たちのチームを去ったばかりの開発者によって書かれました。それを念頭に置いて、いくつかの制限があります:/。
開発者は以前、List と Tree のクロスのようなコードを書いていました。ユーザー インターフェイスでは、ツリー構造です。ただし、コードではリストです。少し奇妙です。ここでは、2 つの主要なクラスが定義されています。
public class TreeBranch
{
public Guid ID { get; set; }
}
public class TreeItem
{
public Guid ID { get; set; }
public Guid TreeBranchID { get; set; }
public Guid? ParentTreeItemID { get; set; }
public int Level { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime? MarkedOn { get; set; }
}
したがって、TreeBranch はデータベース テーブルに格納され、TreeItem はデータベース テーブルに格納されます。MarkedOn 値が NULL である特定の TreeBranchID を持つすべての TreeItem 要素を返すクエリが実行されます。それはこれをリストします:
List<TreeItem> treeItems = GetTreeBranchItems("someID");
treeItems.Sory(new TreeItemComparer());
私の TreeItemComparer クラスは次のようになります。
public class TreeItemComparer: IComparer<TreeItem>
{
// allow us to look up parent Items by GUID
IDictionary<Guid, TreeItem> itemLookup;
public TreeItemComparer(IEnumerable<TreeItem> list)
{
itemLookup = list.ToDictionary(item => item.ID);
foreach (var item in list)
SetLevel(item);
}
public int SetLevel(TreeItem item)
{
if ((item.Level == 0) && (item.ParentTreeItemID != Guid.Empty))
{
if (itemLookup.ContainsKey(item.ParentTreeItemID))
item.Level = 1 + SetLevel(itemLookup[item.ParentTreeItemID]);
}
else if (item.ParentTreeItemID == Guid.Empty)
item.Level = 1;
return item.Level;
}
public int Compare(TreeItem x, TreeItem y)
{
// see if x is a child of y
while (x.Level > y.Level)
{
if ((x.ParentTreeItemID == y.ID) || (x.ParentTreeItemID == Guid.Empty))
return 1;
x = itemLookup[x.ParentTreeItemID];
}
// see if y is a child of x
while (y.Level > x.Level)
{
if ((y.ParentTreeItemID == x.ID) || (y.ParentTreeItemID == Guid.Empty))
return -1;
}
// x and y are not parent-child, so find common ancestor
while (x.ParentTreeItemID != y.ParentTreeItemID)
{
if (x.ParentTreeItemID != Guid.Empty)
x = itemLookup[x.ParentTreeItemID];
if (y.ParentTreeItemID != Guid.Empty)
y = itemLookup[y.ParentTreeItemID];
}
// compare createDate of children of common ancestor
return x.CreatedOn.CompareTo(y.CreatedOn);
}
}
このコードは機能しますが、1 つの例外があります。折に触れて、木が折れてしまいます。たとえば、次のような構造があるとします。
Item 1
Item 1-A (Imagine this TreeItem has a MarkedOn value that is NOT null)
Item 1-A-a
Item 1-A-a-1
Item 1-A-b
Item 1-B
上記の例では、実際には次のようにする必要があります。
Item 1
Item 1-B
しかし、私は得ています
Item 1
Item 1-A-a
Item 1-A-a-1
Item 1-A-b
Item 1-B
私の問題は、MarkedOn 値を持つ TreeItem とそのすべての「子」がコレクションの一部であってはならないことです。環境のせいで、データベースに触れることができません:(。同時に、コードでこれを行う方法がわかりません。誰かアイデアはありますか?
ありがとうございました!