Reputation: 805
i am having two lists those contains the same Ids but not in the same order is there a method to sort list 2 to be the same order of list 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
I used simple for loop but i am searching for something better performance wise
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;
}
}
}
Upvotes: 0
Views: 846
Reputation: 4724
Performance wise Miroo your for loops are going to win hands down every time what ever LinQ or fancy way you are being presented currently.
As the Occam's Razor principals says "The simplest answer is most often correct one". Not every time but in this case I think is applies.
For example I have created the simple application below with a stopwatch to measure the time each sort takes. I added your for loop approach and one line sorting approach that I have done.
I run a few tests and your loop is much fasters then my one line of code. Anything you do will add more cycles to the clock there is countless ways into sorting your array I could even reduce mine even further but in the end your loop would be faster.
If your question was not about performance but about elegance, reducing number of lines or even some more robustness then my answer would be different.
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);
}
}
}
Upvotes: 0
Reputation: 9063
You'll need to create the order on the fly. In other words you are actually sorting:
List1: (Id, PositionInList). e.g. [341932, 1], [346447, 2], ... List2: (Id, PositionInList). e.g. [335667, 1], [335743, 2], ...
Create the above types first (Sql/temp tables / row counts or C#/LINQ/Projection)
Then join the 2 Ids... and find the required position.
Then you can sort the result by the position.
Hope that makes sense.
Update... ok it's a little confusing. So was the question ;-)
I think you are saying you have list 1 that defines an order. And you want to sort the 2nd list into the same order.
If so I'd say do this (it's in Sql-like pseudo code).
Your original list:
List1 = 341932,
346447,
354534, ...
Then select this into a list/hash/table , this should contain the original value and a row index (position). There's a variety of ways you can do this depending on your language.
List1WithIndex = 341932, 1
346447, 2
354534, 3 ...
Now take your second list that you want in the same order:
List2 = 335667,335743,335761,338576, ...
Now all you need to do it join/map List2 value to the List1WithIndex Value. Order by Line1WithIndex poisiton and everything should be in the right order... as long as you left join
If that doesn't work or is still gibberish then maybe a more full example, stating langauge / technology may help...
Upvotes: 0
Reputation: 21742
use the first list as part of a key selector.
list2.OrderBy(a=>list1.IndexOf(a.Id))
if the keys are unique and you don't need to keep list1 as-is you can improve performance by removing the the used IDs from 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);
}
}
Upvotes: 2
Reputation: 23462
Ok, as I understand it (from the comments to your question): You have a list of ids and a list of objects that has those ids, now you want the second list sorted according to the first list of ids:
var objectDictionary = List2.ToDictionary(y => y.MediaItemID, y => y);
var newList = new List<YourType>();
List1.ForEach(y => newList.Add(objectDictionary[y.MediaItemID]));
That should work, but if it is better performance I don't know.
Update: Typo on line three in the code, should have been List1
and not List2
, code updated.
Upvotes: 2