IT

다른 목록 ID에서 목록 정렬

lottoking 2020. 7. 25. 10:21
반응형

다른 목록 ID에서 목록 정렬


다음과 같은 식별자가있는 목록이 있습니다.

List<long> docIds = new List<long>() { 6, 1, 4, 7, 2 };

Morover, 다른 <T>항목 목록 이 있으며 위에서 설명한 ID로 표시됩니다.

List<T> docs = GetDocsFromDb(...)

컬렉션 모두에서 두 동일한 순서를 유지 List<T>해야 우리하므로 (검색 엔진 점수 이유로 인해) 항목 이 첫-th 항목 과 동일한 위치 있어야합니다. 그리고이 과정은 GetDocsFromDb()기능 에서 수행 할 수 없습니다 .

필요한 경우 두 번째 목록을 다른 구조 ( Dictionary<long, T>예 :)로 제안 변경하지 않는 것이 좋습니다.

LINQ를 사용하여 "일부 ID에 따른 조정"을 수행하는 간단하고 효율적인 방법이 있습니까?


docs = docs.OrderBy(d => docsIds.IndexOf(d.Id)).ToList();

당신은 지정하지 않기 때문에 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];
    }
}

원하는 것을위한 일반적인 확장입니다.

아마 이런 확장을 사용할 수 있습니다.

var orderDocs = docs.OrderBySequence(docIds, doc => doc.Id);

더 안전한 버전은

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;
        }
    }
}

source정확히 압축되지와 않으면 작동합니다 order.


Jodrell의 답변이 가장 좋지만 실제로 다시 구현했습니다 System.Linq.Enumerable.Join. Join은 또한 Lookup을 사용하고 소스 순서를 유지합니다.

    docIds.Join(
      docs,
      i => i,
      d => d.Id,
      (i, d) => d);

간단한 접근 방법 중 하나는 주문 순서로 압축하는 것입니다.

List<T> docs = GetDocsFromDb(...).Zip(docIds, Tuple.Create)
               .OrderBy(x => x.Item2).Select(x => x.Item1).ToList();

참고 URL : https://stackoverflow.com/questions/15275269/sort-a-list-from-another-list-ids

반응형