C# 从另一个列表 ID 对列表进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15275269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sort a list from another list IDs
提问by Borja López
I have a list with some identifiers like this:
我有一个包含一些标识符的列表,如下所示:
List<long> docIds = new List<long>() { 6, 1, 4, 7, 2 };
Morover, I have another list of <T>
items, which are represented by the ids described above.
此外,我还有另一个<T>
项目列表,它们由上述 id 表示。
List<T> docs = GetDocsFromDb(...)
I need to keep the same order in both collections, so that the items in List<T>
must be in the same position than in the first one (due to search engine scoring reasons). And this process cannot be done in the GetDocsFromDb()
function.
我需要在两个集合中保持相同的顺序,以便项目中的项目List<T>
必须与第一个项目位于相同的位置(由于搜索引擎评分的原因)。而这个过程是无法在GetDocsFromDb()
函数中完成的。
If necessary, it's possible to change the second list into some other structure (Dictionary<long, T>
for example), but I'd prefer not to change it.
如有必要,可以将第二个列表更改为其他结构(Dictionary<long, T>
例如),但我不想更改它。
Is there any simple and efficient way to do this "ordenation depending on some IDs" with LINQ?
是否有任何简单有效的方法可以使用 LINQ 执行此“根据某些 ID 进行排序”?
采纳答案by Denys Denysenko
docs = docs.OrderBy(d => docsIds.IndexOf(d.Id)).ToList();
回答by Albin Sunnanbo
One simple approach is to zip with the ordering sequence:
一种简单的方法是按顺序压缩:
List<T> docs = GetDocsFromDb(...).Zip(docIds, Tuple.Create)
.OrderBy(x => x.Item2).Select(x => x.Item1).ToList();
回答by Jodrell
Since you don't specify T
,
既然你没有指定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];
}
}
Is a generic extension for what you want.
是您想要的通用扩展。
You could use the extension like this perhaps,
也许你可以像这样使用扩展名,
var orderDocs = docs.OrderBySequence(docIds, doc => doc.Id);
A safer version might be
更安全的版本可能是
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;
}
}
}
which will work if source
does not zip exactly with order
.
如果source
不与 .zip 完全压缩,这将起作用order
。
回答by Kladzey
Jodrell's answer is best, but actually he reimplemented System.Linq.Enumerable.Join
. Join also uses Lookup and keeps ordering of source.
Jodrell 的回答是最好的,但实际上他重新实现了System.Linq.Enumerable.Join
. Join 也使用 Lookup 并保持源的顺序。
docIds.Join(
docs,
i => i,
d => d.Id,
(i, d) => d);