List<int> _lstNeedToOrder = new List<int>();
_lstNeedToOrder.AddRange(new int[] { 1, 5, 6, 8 });
//I need to sort this based on the below list.
List<int> _lstOrdered = new List<int>();//to order by this list
_lstOrdered.AddRange(new int[] { 13, 5, 11, 1, 4, 9, 2, 7, 12, 10, 3, 8, 6 });
order will be -->_lstNeedToOrder = 5,1,8,6
我该怎么做?
答案 0 :(得分:19)
简单 - 但效率低下 - 方式是:
var result = _lstNeedToOrder.OrderBy(x => _lstOrdered.IndexOf(x));
另一种方法是使用远方法获得所需的值索引。如果您的值始终在[1 ... n]范围内,则可以将“有序”列表反转为“按值列出的索引列表”。此时你可以使用:
var result = _lstNeedToOrder.OrderBy(x => indexes[x]);
(其中indexes
在0的开头有一个额外的值,只是为了让事情更简单。)
或者,您可以从值到索引创建Dictionary<int, int>
。这将更加通用,因为它可以处理非常广泛的值而不需要占用大量内存。但是字典查找显然不如数组或列表查找效率高。
作为一个不能作为注释格式化的旁注,可以使用集合初始化器简化初始化:
var listToOrder = new List<int> { 1, 5, 6, 8 };
var orderedList = new List<int> { 13, 5, 11, 1, 4, 9, 2, 7, 12, 10, 3, 8, 6 };
答案 1 :(得分:13)
List<int> results = _lstOrdered.Where(item => _lstNeedToOrder.Contains(item)).ToList();
答案 2 :(得分:4)
您可以构建这样的自定义比较器:
public class SequenceComparer<T> : IComparer<T> {
private readonly Dictionary<T, int> indexes;
public SequenceComparer(IEnumerable<T> sequence) {
this.indexes =
sequence
.Select((item, index) => new { Item = item, Index = index })
.ToDictionary(x => x.Item, x => x.Index);
}
public int Compare(T x, T y) {
return indexes[x].CompareTo(indexes[y]);
}
}
现在你可以说
var result = _lstNeedToOrder.OrderBy(x => x, new SequenceComparer(_lstOrdered));
答案 3 :(得分:4)
这很有效:
var lookup = _lstOrdered
.Select((x, n) => new { x, n })
.ToLookup(x => x.x, x => x.n);
var query =
from x in _lstNeedToOrder
let rank = lookup[x]
.DefaultIfEmpty(int.MaxValue)
.First()
orderby rank
select x;
答案 4 :(得分:2)
另一种选择是使用Intersect
,它保证按照它们在第一个序列中出现的顺序返回元素。
所以,在这个例子中
var result = _lstOrdered.Intersect(_lstNeedToOrder);
根据需要产生{ 5, 1, 8, 6}
。
答案 5 :(得分:1)
在中间字典中保存订单......
// dict key will be the values of _lstOrdered, value will be the index of the
// key in _lstOrdered
// I'm using a seldom used .Select overload that returns the current value
// plus its index (ix)
var dict = _lstOrdered.Select((p, ix) => new { Value = p, Ix = ix })
.ToDictionary(p => p.Value, p => p.Ix);
// note that this will explode if _lstNeedToOrder contains values outside
// _lstOrdered.
_lstNeedToOrder.Sort((p, q) => dict[p] - dict[q]);
.Sort
方法就地排序,因此将订购_lstNeedToOrder。