J'ai 2 objets de liste, l'un est juste une liste d'entiers, l'autre est une liste d'objets mais les objets ont une propriété ID.
Ce que je veux faire, c'est trier la liste des objets par son ID dans le même ordre de tri que la liste des entrées.
Je joue depuis un moment maintenant essayant de le faire fonctionner, jusqu'à présent pas de joie,
Voici ce que j'ai jusqu'à présent ...
//**************************
//*** 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;
}
L'intérêt est que lorsqu'un utilisateur recherche des membres, ils s'affichent d'abord dans un ordre aléatoire, puis s'ils cliquent sur la page 2, ils restent dans cet ordre et les 20 résultats suivants s'affichent.
J'ai lu sur l'ICompare que je peux utiliser comme paramètre dans la clause Linq.OrderBy, mais je ne trouve aucun exemple simple.
J'espère une solution de style LINQ élégante et très simple, et je peux toujours espérer.
Toute aide est très appréciée.
Une autre approche LINQ:
var orderedByIDList = from i in ids
join o in objectsWithIDs
on i equals o.ID
select o;
Une façon de le faire:
List<int> order = ....;
List<Item> items = ....;
Dictionary<int,Item> d = items.ToDictionary(x => x.ID);
List<Item> ordered = order.Select(i => d[i]).ToList();
Pas une réponse à cette exacte question, mais si vous avez deux tableaux, il y a une surcharge de Array.Sort
qui prend le tableau à trier et un tableau à utiliser comme "clé"
https://msdn.Microsoft.com/en-us/library/85y6y2d3.aspx
Méthode Array.Sort (Array, Array)
Trie une paire d'objets de tableau unidimensionnels (l'un contient les clés et l'autre contient les éléments correspondants) en fonction des clés du premier tableau à l'aide de l'implémentation IComparable de chaque clé.
Join
est le meilleur candidat si vous voulez faire correspondre le nombre entier exact (si aucune correspondance n'est trouvée, vous obtenez une séquence vide). Si vous voulez simplement obtenir l'ordre de tri de l'autre liste (et à condition que le nombre d'éléments dans les deux listes soit égal), vous pouvez utiliser Zip .
var result = objects.Zip(ints, (o, i) => new { o, i})
.OrderBy(x => x.i)
.Select(x => x.o);
Assez lisible.
Voici une méthode d'extension qui encapsule réponse de Simon D. pour les listes de tout type.
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);
}
L'utilisation est quelque chose comme:
var sorted = toSort.SortBy(sortKeys, i => i.Key);
Une solution possible:
myList = myList.OrderBy(x => Ids.IndexOf(x.Id)).ToList();
Remarque: utilisez-le si vous travaillez avec In-Memory
répertorie, ne fonctionne pas pour le type IQueryable
, car IQueryable
ne contient pas de définition pour IndexOf