これを行う再帰的な方法は次のとおりです。
private void DeleteNode(IList<Node> nodes, Guid id)
{
Node nodeToDelete = null;
foreach (var node in nodes)
{
if (node.Id == id)
{
nodeToDelete = node;
break;
}
DeleteNode(node.Children, id);
}
if (nodeToDelete != null)
{
nodes.Remove(nodeToDelete);
}
}
すべての操作を 1 つのループにまとめたい場合は、for ループを使用します。私の意見では、読むのははるかに難しいです。
private void DeleteNode(IList<Node> nodes, int id)
{
for (var index = 0; index < nodes.Count; index++)
{
var currentNode = nodes[index];
if (currentNode.Id == id)
{
nodes.Remove(currentNode);
break;
}
DeleteNode(currentNode.Children, id);
}
}
もう 1 つの方法は、すべての要素を含むフラット (非階層) リストまたはディクショナリ(最も簡単な方法!) を作成することです。子の親 ID を含む別のプロパティを追加できます。場合によっては、特にアイテムがたくさんある深いツリーがある場合は、この方法の方がはるかにパフォーマンスが高くなります。特定のアイテムを削除する場合は、次のようにします。
private void DeleteNode(IList<Node> flatNodes, Guid id)
{
var nodeToDelete = flatNodes.FirstOrDefault(n => n.Id == id);
if (nodeToDelete != null)
{
var parent = flatNodes.First(n => n.Id == nodeToDelete.ParentId);
parent.Children.Remove(nodeToDelete);
}
}
private void DeleteNodeFromFlatDictionary(IDictionary<Guid, Node> flatNodes, Guid id)
{
if (!flatNodes.ContainsKey(id)) return;
var nodeToDelete = flatNodes[id];
flatNodes[nodeToDelete.ParentId].Children.Remove(id);
}
ただし、UI に変更を認識させたい場合は、 を使用する必要がありObservableCollection<Node>
ます。