int[] OrderedListToFollow = {1,2,4,5}
int[] ListB = {2,3,4,8,9}
基于上面的两个列表,我需要根据OrderedListToFollow中定义的顺序对ListB进行排序。由于3,8,9不是OrderedListToFollow的一部分,因此可以按任何顺序出现,因此可接受的解决方案可以具有以下任何一种:
int[] ListB = {2,4,3,8,9}
int[] ListB = {2,4,8,3,9}
int[] ListB = {2,4,9,3,8}
我尝试按照以下方式执行此操作,但它没有订购它:
ListB = ListB.OrderBy(id => OrderedListToFollow.ToList().IndexOf(id)).ToArray();
编辑
上面的订单有效,但它首先放置OrderedListToFollow中不存在的项目,然后放置剩余的。
答案 0 :(得分:2)
排序方法的问题是,如果找不到该项,IndexOf方法将返回-1。因此,您存在的所有项目"外部"给定的排序方案放在集合的开头,因为它们的索引为-1。
您可以尝试使用条件返回索引(如果找到)和当前索引:
var c = ListB.Count();
ListB = ListB
.OrderBy(id => OrderedListToFollow.Contains(id)
? OrderedListToFollow.ToList().IndexOf(id)
: c + 1 // This will always pace invalid objects at the end
);
答案 1 :(得分:2)
如上所述,除了将结果放在开头之外,它已经开始工作了。要解决这个问题,我会添加一个扩展方法:
public static int IndexOfOrMax(this IEnumerable<T> source, T item)
{
int index = source.IndexOf(item);
return index == -1 ? int.MaxValue : index;
}
另请注意,您无需在ToList
上致电OrderedListToFollow
- 目前您正在调用 lot ,效率非常低。使用上述扩展方法,您可以使用:
int[] orderedListToFollow = {1,2,4,5};
int[] listB = {2,3,4,8,9};
listB = listB.OrderBy(id => orderedListToFollow.IndexOfOrMax(id)).ToArray();
答案 2 :(得分:0)
这样的事情怎么样:
int[] OrderedListToFollow = {1,2,4,5};
int[] ListB = {2,3,4,8,9};
List<int> ListC = new List<int>();
ListC.AddRange(OrderedListToFollow.Where(p => ListB.Contains(p)));
ListC.AddRange(ListB.Where(p => !OrderedListToFollow.Contains(p)));
这会给你一个这样的结果:
2 4 3 8 9
答案 3 :(得分:0)
你可以使用Join和Except来做到这一点,好处是他们同时进行了O(n)操作(由于他们在实现中都使用了Hashtables)。这个片段取决于OrderedListToFollow确实是有序的假设。
int[] OrderedListToFollow = new[]{1,2,4,5};
int[] ListB = new[]{3,4,8,2,9};
var existing = from o in OrderedListToFollow
join l in ListB on o equals l
select l;
var other = ListB.Except(OrderedListToFollow);
var result = existing.Concat(other);