Sortuj listę z innego identyfikatora listy
Mam listę z takimi identyfikatorami:
List<long> docIds = new List<long>() { 6, 1, 4, 7, 2 };
Co więcej, mam jeszcze jedną listę <T>
elementów, które są reprezentowane przez identyfikatory opisane powyżej.
List<T> docs = GetDocsFromDb(...)
Muszę zachować tę samą kolejność w obu kolekcjach, aby pozycje w List<T>
musiały znajdować się w tej samej pozycji, co w pierwszej (ze względu na punktację wyszukiwarek). I tego procesu nie można wykonać w funkcji GetDocsFromDb()
.
W razie potrzeby można zmienić drugą listę na inną struktura (Dictionary<long, T>
na przykład), ale wolałbym tego nie zmieniać.
Czy Jest jakiś prosty i skuteczny sposób, aby zrobić to "ordenation w zależności od niektórych IDs" z LINQ?
3 answers
docs = docs.OrderBy(d => docsIds.IndexOf(d.Id)).ToList();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-07 15:42:22
Ponieważ nie podajesz 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];
}
}
Jest ogólnym rozszerzeniem tego, co chcesz.
Możesz użyć rozszerzenia w ten sposób być może,
var orderDocs = docs.OrderBySequence(docIds, doc => doc.Id);
Bezpieczniejszą wersją może być
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;
}
}
}
Które będzie działać, jeśli source
nie zapina się dokładnie za pomocą order
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-07 16:00:37
Jednym prostym podejściem jest zip z sekwencją porządkową:
List<T> docs = GetDocsFromDb(...).Zip(docIds, Tuple.Create)
.OrderBy(x => x.Item2).Select(x => x.Item1).ToList();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-07 15:44:00