想象一下,您有一个名为List<Foo>
的列表。
Foo
是一个抽象类,因此可以是FooA
,FooB
,FooC
或FooD
。我希望List<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完成它。
答案 0 :(得分:6)
您可以按类型对项目进行分组,按类型对组进行排序并交错组:
var groups = items.GroupBy(x => x.GetType())
.OrderBy(g => orderedTypes.IndexOf(g.Key))
.ToList();
var result = groups.First().Interleave(groups.Skip(1).ToArray());
使用Interleave method from EvenMoreLINQ。
foreach (var item in result)
{
Console.WriteLine(item.GetType());
}
输出:
FooA
FooB
FooC
FooD
FooA
FooB
FooC
FooA
FooA
答案 1 :(得分:1)
对类型进行分组,然后遍历项目,每次添加一组。类似的东西:
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]);
}
}
}
答案 2 :(得分:0)
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
中使用的那些)。
我使用{{ 1}}存储模式顺序,因为它具有O(1)复杂性。
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>