сортировать список, чтобы он был похож на другой список - PullRequest
0 голосов
/ 01 августа 2011

У меня есть два списка, которые содержат одинаковые идентификаторы, но не в том же порядке Есть ли способ сортировки списка 2 по порядку списка 2

List 1:
Views IDs: 341932,346447,354534,335743,351166,350016,352398,354390,351389,342070,335667,338576,335761,354504,352421,350090,342114,351396,354436,355624,352339,352378,355580

List 2: 
FromLol Ids: 335667,335743,335761,338576,341932,342070,342114,346447,350016,350090,351166,351389,351396,352339,352378,352398,352421,354390,354436,354504,354534,355580,355624

Я использовал простой цикл, но я ищу что-то лучшее с точки зрения производительности

for (int i = 0; i < List1.Count; i++)
{
    for (int j = 0; j < List2.Count; j++) 
    {
        if (List1[i].MediaItemIdId == List2[j].MediaItemID) 
        {
            TempList.Add(List2[j]);
            break;
        }
    }
}

Ответы [ 4 ]

2 голосов
/ 01 августа 2011

Хорошо, насколько я понимаю (из комментариев к вашему вопросу): у вас есть список идентификаторов и список объектов, которые имеют эти идентификаторы, теперь вы хотите, чтобы второй список был отсортирован в соответствии с первым списком идентификаторов:

var objectDictionary = List2.ToDictionary(y => y.MediaItemID, y => y);
var newList = new List<YourType>();
List1.ForEach(y => newList.Add(objectDictionary[y.MediaItemID]));

Это должно работать, но если это лучшая производительность, я не знаю.

Обновление: Опечатка в третьей строке кода должна была быть List1, а не List2, код обновлен.

2 голосов
/ 01 августа 2011

использовать первый список как часть ключевого селектора.

 list2.OrderBy(a=>list1.IndexOf(a.Id))

если ключи уникальны и вам не нужно сохранять list1 как есть, вы можете повысить производительность, удалив используемые идентификаторы из list1.

public static IList<T> OrderBy<T, K>(this IList<T> self, Func<T, K> keySelector, IList<K> sortedlist){
            var indices = GetIndices(self, keySelector, sortedlist).Reverse().GetEnumerator();
            indices.MoveNext();
            var result = new List<T>();
            for(int i = self.Count-1;i>=0;i--){
                result.Insert(indices.Current,self[i]);
                indices.MoveNext();
            }
            return result;
        }

        private static IEnumerable<int> GetIndices<T,K>(IEnumerable<T> self, Func<T, K> keySelector, IList<K> sortedlist)
        {
            foreach (var elem in self)
            {
                var key = keySelector(elem);
                yield return sortedlist.IndexOf(key);
            }
        }
0 голосов
/ 01 августа 2011

Мудрая производительность Miroo, ваши петли for будут выигрывать руки каждый раз, когда бы вы ни представляли LinQ, или какой бы модный вам ни был представлен в настоящее время.

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

Например, я создал простое приложение ниже с секундомером, чтобы измерить время, необходимое для каждой сортировки. Я добавил ваш подход для цикла и метод сортировки одной строкой, который я сделал.

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

Если бы ваш вопрос был не о производительности, а об элегантности, сокращении количества линий или даже большей устойчивости, тогда мой ответ был бы другим.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> list1 = new List<int> { 341932,346447,354534,335743,351166,350016,352398,354390,351389,342070,335667,338576,335761,354504,352421,350090,342114,351396,354436,355624,352339,352378,355580};

            List<int> list2 = new List<int> { 335667,335743,335761,338576,341932,342070,342114,346447,350016,350090,351166,351389,351396,352339,352378,352398,352421,354390,354436,354504,354534,355580,355624};

            List<int> list3 = new List<int>();

            Stopwatch watch = new Stopwatch();

            watch.Start();

            for (int i = 0; i < list1.Count; i++)
            {
                for (int j = 0; j < list2.Count; j++) 
                {
                    if (list1[i] == list2[j]) 
                    {
                        list3.Add(list2[j]);
                        break;
                    }
                }
            }

            watch.Stop();

            Console.WriteLine("Time {0}", watch.ElapsedMilliseconds);

            list3.Clear();

            watch.Reset();

            watch.Start();

            list2.Intersect(list1).OrderBy(o => list1.IndexOf(o)).All(a => { list3.Add(a); return true; });

            watch.Stop();

            Console.WriteLine("Time {0}", watch.ElapsedMilliseconds);
        }
    }
}
0 голосов
/ 01 августа 2011

Вам нужно будет создать заказ на лету.Другими словами, вы на самом деле сортируете:

List1: (Id, PositionInList).например, [341932, 1], [346447, 2], ... List2: (Id, PositionInList).например, [335667, 1], [335743, 2], ...

Сначала создайте вышеуказанные типы (Sql / temp таблицы / количество строк или C # / LINQ / Projection)

Затем присоединитесь2 идентификатора ... и найдите требуемую позицию.

Затем вы можете отсортировать результат по позиции.

Надеюсь, что это имеет смысл.


Обновление ... хорошо, это немного сбивает с толку.Так был вопрос; -)

Я думаю вы говорите, что у вас есть список 1, который определяет порядок.И вы хотите отсортировать второй список в том же порядке.

Если это так, я бы сказал, сделайте это (он в Sql-подобном псевдокоде).

Ваш оригинальный список:

List1 = 341932, 
             346447, 
             354534,    ...

Затем выберите это в список / хэш / таблицу, которая должна содержать исходное значение и индекс строки (позиция).Существует множество способов сделать это в зависимости от вашего языка.

List1WithIndex = 341932, 1
                 346447, 2
                 354534, 3   ...

Теперь возьмите второй список, который вам нужен, в том же порядке:

List2 = 335667,335743,335761,338576, ...

Теперь все, что вам нужносделать это соединить / сопоставить значение List2 со значением List1WithIndex.Порядок по Line1WithIndex poisiton и все должно быть в правильном порядке ... до тех пор, пока вы не присоединились...

...