Ich habe 2 Listenobjekte, eines ist nur eine Liste von Ints, das andere ist eine Liste von Objekten, aber die Objekte haben eine ID-Eigenschaft.
Was ich tun möchte, ist die Liste der Objekte nach ihrer ID in der gleichen Sortierreihenfolge wie die Liste der Ints zu sortieren.
Ich habe eine Weile herumgespielt und versucht, es zum Laufen zu bringen, bisher keine Freude,
Hier ist was ich bisher habe ...
//**************************
//*** 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;
}
Der springende Punkt dabei ist, dass ein Benutzer, wenn er nach Mitgliedern sucht, diese zunächst in zufälliger Reihenfolge anzeigt. Wenn er dann auf Seite 2 klickt, bleiben sie in dieser Reihenfolge und die nächsten 20 Ergebnisse werden angezeigt.
Ich habe über den ICompare gelesen, den ich als Parameter in der Linq.OrderBy-Klausel verwenden kann, aber ich kann keine einfachen Beispiele finden.
Ich hoffe auf eine elegante, sehr einfache Lösung im LINQ-Stil, und ich kann immer hoffen.
Jede Hilfe wird am meisten geschätzt.
Antworten:
Ein weiterer LINQ-Ansatz:
var orderedByIDList = from i in ids join o in objectsWithIDs on i equals o.ID select o;
quelle
Eine Möglichkeit, dies zu tun:
List<int> order = ....; List<Item> items = ....; Dictionary<int,Item> d = items.ToDictionary(x => x.ID); List<Item> ordered = order.Select(i => d[i]).ToList();
quelle
order.Where(d.ContainsKey).Select(...)
oder Select / SelectMany mit einer längeren Funktion, die TryGetValue verwendet, löst dieses Problem.Keine Antwort auf diese genaue Frage, aber wenn Sie zwei Arrays haben , gibt es eine Überladung
Array.Sort
, bei der das Array sortiert und ein Array als 'Schlüssel' verwendet werden muss.https://msdn.microsoft.com/en-us/library/85y6y2d3.aspx
quelle
Join
ist der beste Kandidat, wenn Sie mit der exakten Ganzzahl übereinstimmen möchten (wenn keine Übereinstimmung gefunden wird, erhalten Sie eine leere Sequenz). Wenn Sie lediglich die Sortierreihenfolge der anderen Liste abrufen möchten (und vorausgesetzt, die Anzahl der Elemente in beiden Listen ist gleich), können Sie Zip verwenden .var result = objects.Zip(ints, (o, i) => new { o, i}) .OrderBy(x => x.i) .Select(x => x.o);
Ziemlich lesbar.
quelle
ints
Liste zunächst sortiert werden. Die akzeptierte Antwort nicht.ints
trotzdem, um die Sortierreihenfolge zu erhalten, daher müssen die Ints nicht erst bestellt werden.Join
eine Art von Problem gelöst wird.Zip
ist für etwas anderes. Der Titel lautet "Sortieren einer Sammlung in der Reihenfolge einer anderen Sammlung" und für die überwiegende Mehrheit würde dies bedeuten, was ich in der Antwort gewählt habe. Ich habe gerade eine alternative Antwort hinterlassen, die Menschen mit ähnlichen Problemen in Zukunft helfen könnte. Wenn die Sortierung auf der ID basiert, muss natürlich auch ein geeigneter Vergleicher angegeben werden (imOrderBy
)Hier ist eine Erweiterungsmethode, die die Antwort von Simon D. für Listen eines beliebigen Typs kapselt .
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); }
Verwendung ist so etwas wie:
var sorted = toSort.SortBy(sortKeys, i => i.Key);
quelle
Eine mögliche Lösung:
Hinweis: Verwenden Sie diese
In-Memory
Option, wenn Sie mit Listen arbeiten, die nicht für denIQueryable
TypIQueryable
funktionieren , da sie keine Definition für enthältIndexOf
quelle
docs = docs.OrderBy(d => docsIds.IndexOf(d.Id)).ToList();
quelle