Вроде один список другим


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

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

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

вот что у меня до сих пор...

//**************************
//*** 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 71

6 ответов:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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