5

と呼ばれるリストがあると想像してくださいList<Foo>

Fooは抽象クラスであるため、これは、、、またはFooAになります。そして、この要素をタイプごとに順番に並べ替えることができる拡張機能が必要です。FooBFooCFooDList<T>

たとえば、9つの要素が含まれているとします。

FooA, FooA, FooB, FooD, FooC, FooC, FooA, FooB, FooA

その後、タイプ別の注文になります。

FooA, FooB, FooC, FooD, FooA, FooB, FooC, FooA, FooA

関数を指定した順序で並べ替えることができるようにしようとしています。この場合はIEです。

new[] { typeof(FooA), typeof(FooB), typeof(FooC), typeof(FooD) }

この拡張機能を作成しようとしましたが、何も取得できません。少し手伝ってもらえますか?LINQで実現できると思います。

4

3 に答える 3

6

アイテムをタイプ別にグループ化し、グループをタイプ別にソートし、グループをインターリーブできます。

var groups = items.GroupBy(x => x.GetType())
                  .OrderBy(g => orderedTypes.IndexOf(g.Key))
                  .ToList();

var result = groups.First().Interleave(groups.Skip(1).ToArray());

EvenMoreLINQのInterleave メソッドを使用します。

foreach (var item in result)
{
    Console.WriteLine(item.GetType());
}

出力:

FooA
FooB
FooC
FooD
FooA
FooB
FooC
FooA
FooA
于 2012-08-25T20:22:32.063 に答える
0

listソートする要素のコレクションです。
pattern特定の順序での要素のコレクションです。に従って順序付けされた
resultの要素のコレクションです。listpattern

var list = new List<Foo> { new FooA(), new FooB(), new FooC(), new FooA(), new FooC(), new FooA(), new FooD() };
var pattern = new Foo[] { new FooB(), new FooC(), new FooD(), new FooA() };

var result = list.OrderBy(p => p, new MyFooComparer(pattern));

MyFooComparerinterface を実装するクラスがありますIComparer<>。比較は、コレクション内
のそれぞれの位置に基づいています。要素は複製してはならず、すべてのタイプ(少なくとも で使用されるもの) を含む必要があります。O(1)の複雑さがあるため、パターンの順序を保存していました。FoopatternpatternFoolist
Dictionary<>

public class MyFooComparer : IComparer<Foo>
{
    private readonly Dictionary<Type, int> _pattern;
    public MyFooComparer(IEnumerable<Foo> pattern)
    {
        _pattern = new Dictionary<Type, int>();
        int i = 0;
        foreach (var foo in pattern)
        {
            _pattern.Add(foo.GetType(), i);
            i++;
        }
    }

    public int Compare(Foo x, Foo y)
    {
        var xVal = _pattern[x.GetType()];
        var yVal = _pattern[y.GetType()];
        return xVal.CompareTo(yVal);
    }
}

呼び出し後:

        foreach (var foo in result)
        {
            Console.WriteLine(foo.GetType().Name);
        }

によるとpattern、次のものが得られます。

FooB
FooC
FooC
FooD
FooA
FooA
FooA

編集:

拡張子List<Foo>:

static class MyExtension
{
    public static IEnumerable<Foo> OrderByFoo<T>(this List<Foo> list, IEnumerable<Foo> patern)
    {
        return list.OrderBy(p => p, new MyFooComparer(patern));
    }
}
于 2012-09-04T13:46:31.810 に答える