根据固定格式订购列表

时间:2014-05-29 15:25:47

标签: c#

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中不存在的项目,然后放置剩余的。

4 个答案:

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