把一个列表按另一个排序

我有两个列表对象,一个只是一个整数列表,另一个是一个对象列表,但对象有一个 ID 属性。

我想要做的是按照 ID 对对象列表进行排序,排序顺序与 int 列表相同。

我已经玩了一段时间了现在试图让它工作,到目前为止没有乐趣,

这是我目前掌握的情况。

//**************************
//*** 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 风格的解决方案,我总是希望。

非常感谢你的帮助。

38858 次浏览

一种方法是:

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


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


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

另一种 LINQ 方法:

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

如果您想匹配精确的整数,Join是最好的候选者(如果没有找到匹配,您将得到一个空序列)。如果只想获取另一个列表的排序顺序(并且两个列表中的元素数量相等) ,可以使用 什么都没有

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

很容易读懂。

下面是一个扩展方法,它封装了任何类型的列表的 西蒙 · D 的回答

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

这不是这个 一模一样问题的答案,但是如果您有两个 数组,那么有一个重载的 Array.Sort,它使用数组进行排序,并使用一个数组作为“键”

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

数组。排序方法(数组,数组)
对一对一维 Array 对象(其中一个包含键)进行排序 中的键,而另一个则包含相应的项目) 第一个 Array 使用每个键的 IComable 实现。

一种可能的解决办法是:

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

注意: 如果您使用的是 In-Memory列表,则不适用于 IQueryable类型,因为 IQueryable不包含 IndexOf的定义

docs = docs.OrderBy(d => docsIds.IndexOf(d.Id)).ToList();