从另一个列表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();