4

私には次のような親子関係があります。

public class MyType {

    public IList<MyType> Children {get;set;}
    public int Order {get;set;}

}

各レベルが順番になるようにリストを選択したいと思います。

私はこれをトップレベルで簡単に行うことができます:

mylist.Children.OrderBy(x => x.Order)

しかし、どのように私は子供たちのすべてのセットのためにそれをするのですか?

最終結果は、すべての子を含むリストまたはタイプになり、そこにある子(など)はすべてOrderによって正しくソートされます。

ありがとう。

4

5 に答える 5

6

MyType次のように1つのメソッドを追加することで、再帰順序を実行できます。

public class MyType
{
    public IList<MyType> Childrens { get; set; }
    public int Order { get; set; }

    public void RecursiveOrder()
    {
        Childrens = Childrens.OrderBy(x => x.Order)
            .ToList();

        Childrens.ToList().ForEach(c => c.RecursiveOrder());
    }
} 
于 2012-09-15T08:38:06.067 に答える
2

SortedListを基になる子コレクションとして使用すると、子をソートしたままにすることができます。Values次に、プロパティを公開して値を取得できます。orderリストに追加するときは、アイテムをキーで入力するだけです。

例えば、

public class MyType
{
    public MyType(int order)
    {
        this.order = order;
    }

    private int order;
    private SortedList<int, MyType> children = new SortedList<int, MyType>();

    public int Order { get { return order; } }
    public IList<MyType> Children { get { return children.Values; } }

    public void AddChild(MyType child)
    {
        children.Add(child.order, child);
    }
}

それ以外の場合は、おそらくリストを再帰的に並べ替えたいと思うでしょう。ここで LINQ を使用するのは適切ではありません。せいぜい、LINQ を使用すると、並べ替えられた順序で子を反復処理できますが、リスト インスタンスを並べ替えられたバージョンに置き換えない限り、基になるリストは実際には並べ替えられません。基になるリストにSort()(ジェネリックList<T>にある) メソッドがある場合は、それを使用します。

private List<MyType> children;
public void EnsureSorted()
{
    children.Sort();
    foreach (var child in children)
        child.EnsureSorted();
}

ただし、ソートされたリストから始める方がはるかに簡単です。

于 2012-09-15T07:54:49.487 に答える
1

主なアクセス パターンになる場合は、データを並べ替えて保存するのが最も簡単な方法であるという Jeff の意見に同意します。しかし、Linq でこれを本当にやりたいとしましょう。

まず、2 レベルの順序付けのみが必要であることがわかっている場合は、次のようにすることができます。

myList.Children.OrderBy(x => x.Order)
    .Select(c => c.Children.OrderBy(x => x.Order))

しかし、完全に再帰的な順序付けが本当に必要な場合はどうすればよいでしょうか?

delegate IEnumerable<MyType> RecursiveFunc(MyType data, RecursiveFunc self);
RecursiveFunc op = (data, func) => data.Children.OrderBy(x => x.Order)
    .Select(x => func(x, func));

IEnumerable<MyType> result = op(myList, op);

書いてるだけで頭が痛くなるし、実行もしてないので頑張ってください!結局のところ、linq式(ラムダ)をそれ自体に渡し、ツリーの下に再帰的に適用します。

于 2012-09-15T15:49:58.937 に答える
0

最終結果が(ネストされた子を持つ親のリストではなく)単に子のリストである必要がある場合は、SelectMany

IEnumerable<Child> result  = parents
    .SelectMany(p => p.Children)
    .OrderBy(child => child.Order);
于 2012-09-15T16:02:08.473 に答える
0

これを試してください

mylist.Children.OrderBy(x => x.Order).ThenBy( x => x.order).ToList();
于 2012-09-15T08:11:29.753 に答える