Подтвердить что ты не робот

Сортировка одного списка другим

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

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

Я играл некоторое время, пытаясь заставить его работать, до сих пор нет радости,

Вот что я до сих пор...

//**************************
//*** 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, и я всегда надеюсь.

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

4b9b3361

Ответ 1

Другой подход LINQ:

 var orderedByIDList = from i in ids 
                       join o in objectsWithIDs
                       on i equals o.ID
                       select o;

Ответ 2

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

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

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

List<Item> ordered = order.Select(i => d[i]).ToList();

Ответ 3

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

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

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

Ответ 4

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

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

Довольно читаемый.

Ответ 5

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

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

Ответ 6

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

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

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