docs = docs.OrderBy(d => docsIds.IndexOf(d.Id)).ToList();
Since you don't specify 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
.
Jodrell's answer is best, but actually he reimplemented System.Linq.Enumerable.Join
. Join also uses Lookup and keeps ordering of source.
docIds.Join(
docs,
i => i,
d => d.Id,
(i, d) => d);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With