我有一个带有这样一些标识符的列表:
List<long> docIds = new List<long>() { 6, 1, 4, 7, 2 };
此外,我还有一个<T>项的列表,由上面描述的id表示。
List<T> docs = GetDocsFromDb(...)
我需要在两个集合中保持相同的顺序,以便List<T>中的项必须与第一个中的项处于相同的位置(由于搜索引擎评分原因)。这个过程不能在GetDocsFromDb()函数中完成。
如果有必要,可以将第二个列表更改为其他结构(例如Dictionary<long, T>),但我宁愿不更改它。
有什么简单有效的方法来做这个“ordenation依赖于一些id”与LINQ?
因为你没有指定T,
public static 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);
一个更安全的版本可能是
public static 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;
}
}
}
如果源没有完全按照顺序压缩,这将工作。