0

効率的な方法で項目リストからツリーを構築する方法について、いくつかの提案を得たいと思います

 public class Item
    {
        public Item(int id, int? parentId)
        {
            Id = id;
            ParentId = parentId;
        }

        public int Id { get; private set; }
        public int? ParentId { get; private set; }
        public List<Item> SubItems  { get; set; }
    }

    private Item BuildATree()
    {
        var items = new List<Item>()
                        {
                            new Item(1, null),
                            new Item(2, 1),
                            new Item(3, 1),
                            new Item(4, 1),
                            new Item(5, 2),
                            new Item(6, 2),
                            new Item(7, 4),
                            new Item(8, 7),
                            new Item(9, 1),
                        };

        //Build a tree out of list items
    }

私が期待している結果は、各アイテムがその親の SubItems リストにあることです

IDが冗長になるため、必ずしも同じItemクラスを使用する必要はありません

4

3 に答える 3

2

十分に効率的なソリューション

private void RecursiveBuilder(ref Item i, IEnumerable<Item> li)
{
    var item = i;
    i.SubItems = (from n in li where n.ParentId == item.Id select n).ToList();
    i.SubItems.ForEach(f => RecursiveBuilder(ref f, li));
}
于 2012-06-11T11:46:37.097 に答える
2

私はLINQを使用します:

//Build a tree out of list items
foreach (Item item in items)
{
    item.SubItems = items.Where(i => i.ParentId.Value == item.Id).ToList();
}

更新:

アイテムをある親から別の親に簡単に移動するには、すべてのアイテムに親アイテムへの参照を保存する必要があります。何かのようなもの:

public class Item
{
    public Item(int id, int? parentId)
    {
        Id = id;
        ParentId = parentId;
    }

    public int Id { get; private set; }
    public int? ParentId { get; private set; }
    public List<Item> SubItems  { get; set; }

    private Item _parent;
    public Item Parent 
    {
        get { return _parent; }
        set
        {
            if (_parent != null)
                _parent.SubItems.Remove(this);
            _parent = value;
            if (_parent != null)
                _parent.SubItems.Add(this);
        }
    }
}

そのように実装すると、このプロパティを介して新しい親項目を設定するだけで、古い親と新しい親の両方の SubItems コレクションを変更できますが、もう少し複雑なリスト初期化メカニズムも必要になることに注意してください。

于 2012-06-05T11:49:50.927 に答える