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