How to order a list by type?

Imagine you have a list called List<Foo>.

Foo- an abstract class, so it may be FooA, FooB, FooCor FooD. And I would like to have an extension for List<T>where you can order these items by type, but sequentially.

For example, if I have 9 elements.

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

The type order will be sequentially.

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

I am trying so that the function can be ordered in the order you specify, in this case IE, it was:

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

I tried to create this extension but get nothing. Can you help a little? I assume I can accomplish this with LINQ.

+5
source share
3 answers

, :

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

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

Interleave EvenMoreLINQ.

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

:

FooA
FooB
FooC
FooD
FooA
FooB
FooC
FooA
FooA
+6

, . - :

var groups =
  collection.GroupBy(x => x.GetType())
  .ToDictionary(g => g.Key, g => g.ToList());

List<Foo> result = new List<Foo>();
int max = groups.Values.Max(n => n.Count);
for (int i = 0; i < max; i++) {
  foreach (Type  t in sortArray) {
    if (groups[t].Count > i) {
      result.Add(groups[t][i]);
    }
  }
}
+1

list - .
pattern .
result list, pattern.

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));

MyFooComparer, IComparer<>.
Foo pattern. pattern , Foo ( , list).
Dictionary<> O (1) .

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

EDIT:

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));
    }
}
0

All Articles