从另一个列表IDsorting列表

我有一个像这样的标识符的列表:

List<long> docIds = new List<long>() { 6, 1, 4, 7, 2 }; 

莫罗夫,我有另一个<T>项目的列表,这是由上述ID代表。

 List<T> docs = GetDocsFromDb(...) 

我需要在这两个集合中保持相同的顺序,以便List<T>中的项目必须位于与第一个项目相同的位置(由于search引擎评分的原因)。 而这个过程不能在GetDocsFromDb()函数中完成。

如果有必要,可以将第二个列表更改为其他结构(例如Dictionary<long, T> ),但是我不想更改它。

有没有什么简单而有效的方法来做这个“取决于某些ID的定义”与LINQ?

 docs = docs.OrderBy(d => docsIds.IndexOf(d.Id)).ToList(); 

既然你没有指定T

 IEnumerable<T> OrderBySequence<T, TId>( this IEnumerable<T> source, IEnumerable<TId> order, Func<T, TId> idSelector) { var lookup = source.ToDictionary(idSelector, t => t); foreach (var id in order) { yield return lookup[id]; } } 

是你想要的通用扩展。

你也许可以这样使用扩展名,

 var orderDocs = docs.OrderBySequence(docIds, doc => doc.Id); 

一个更安全的版本可能是

 IEnumerable<T> OrderBySequence<T, TId>( this IEnumerable<T> source, IEnumerable<TId> order, Func<T, TId> idSelector) { var lookup = source.ToLookup(idSelector, t => t); foreach (var id in order) { foreach (var t in lookup[id]) { yield return t; } } } 

这将工作,如果source不完全按order压缩。

一个简单的方法是按顺序sorting:

 List<T> docs = GetDocsFromDb(...).Zip(docIds, Tuple.Create) .OrderBy(x => x.Item2).Select(x => x.Item1).ToList();