Сортировать один список за другим - PullRequest
72 голосов
/ 16 октября 2010

У меня есть 2 объекта списка, один - просто список целых, другой - список объектов, но у объектов есть свойство ID.

Я хочу отсортировать список объектов поего идентификатор в том же порядке сортировки, что и в списке целых чисел.

Я уже некоторое время пытаюсь заставить его работать, пока что нет радости,

Вот что у меня такдалеко ...

//**************************
//*** Randomize the list ***
//**************************
if (Session["SearchResultsOrder"] != null)
{
    // save the session as a int list
    List<int> IDList = new List<int>((List<int>)Session["SearchResultsOrder"]);
    // the saved list session exists, make sure the list is orded by this
    foreach(var i in IDList)
    {
        SearchData.ReturnedSearchedMembers.OrderBy(x => x.ID == i);
    }
}
else
{
    // before any sorts randomize the results - this mixes it up a bit as before it would order the results by member registration date                        
    List<Member> RandomList = new List<Member>(SearchData.ReturnedSearchedMembers);
    SearchData.ReturnedSearchedMembers = GloballyAvailableMethods.RandomizeGenericList<Member>(RandomList, RandomList.Count).ToList();

    // save the order of these results so they can be restored back during postback
    List<int> SearchResultsOrder = new List<int>();
    SearchData.ReturnedSearchedMembers.ForEach(x => SearchResultsOrder.Add(x.ID));
    Session["SearchResultsOrder"] = SearchResultsOrder;
}   

Весь смысл в том, что когда пользователь ищет участников, сначала они отображаются в случайном порядке, затем, если они нажимают на страницу 2, они остаются в этом порядке и на следующем20 результатов отображения.

Я читал об ICompare, который я могу использовать в качестве параметра в предложении Linq.OrderBy, но я не могу найти простых примеров.

Я надеюсь на элегантный,очень простое решение в стиле LINQ, я всегда могу на это надеяться.

Любая помощь очень ценится.

Ответы [ 6 ]

117 голосов
/ 16 октября 2010

Еще один LINQ-подход:

 var orderedByIDList = from i in ids 
                       join o in objectsWithIDs
                       on i equals o.ID
                       select o;
25 голосов
/ 16 октября 2010

Один из способов сделать это:

List<int>  order = ....;
List<Item> items = ....;

Dictionary<int,Item> d = items.ToDictionary(x => x.ID);

List<Item> ordered = order.Select(i => d[i]).ToList();
13 голосов
/ 23 февраля 2016

Не ответ на этот точный вопрос, но если у вас есть два массива , существует перегрузка Array.Sort, которая принимает массив для сортировки и массив для использования в качестве «ключа»

https://msdn.microsoft.com/en-us/library/85y6y2d3.aspx

Метод Array.Sort (Array, Array)
Сортирует пару одномерных объектов Array (один содержит ключи а другой содержит соответствующие элементы) на основе ключей в первый массив, использующий реализацию IComparable каждого ключа.

9 голосов
/ 15 октября 2013

Join - лучший кандидат, если вы хотите найти точное целое число (если совпадение не найдено, вы получите пустую последовательность).Если вы хотите просто получить порядок сортировки другого списка (и при условии, что количество элементов в обоих списках равно), вы можете использовать Zip .

var result = objects.Zip(ints, (o, i) => new { o, i})
                    .OrderBy(x => x.i)
                    .Select(x => x.o);

Довольно читабельно.

4 голосов
/ 01 октября 2015

Вот метод расширения, который включает ответ Саймона Д. для списков любого типа.

public static IEnumerable<TResult> SortBy<TResult, TKey>(this IEnumerable<TResult> sortItems,
                                                         IEnumerable<TKey> sortKeys,
                                                         Func<TResult, TKey> matchFunc)
{
    return sortKeys.Join(sortItems,
                         k => k,
                         matchFunc,
                         (k, i) => i);
}

Использование это что-то вроде:

var sorted = toSort.SortBy(sortKeys, i => i.Key);
0 голосов
/ 21 августа 2017

Одно из возможных решений:

myList = myList.OrderBy(x => Ids.IndexOf(x.Id)).ToList();

Примечание: используйте это, если вы работаете со списками In-Memory, не работает для типа IQueryable, поскольку IQueryable не содержитопределение для IndexOf

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...