将一个列表按另一个排序

Posted

技术标签:

【中文标题】将一个列表按另一个排序【英文标题】:Sort one list by another 【发布时间】:2011-04-26 03:31:16 【问题描述】:

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

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

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

这是我目前所拥有的......

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

非常感谢任何帮助。

【问题讨论】:

您是否考虑过在两个列表之间执行 linq 连接然后执行排序? 提示:需要将原始订单保存为字典:id 2 index。 ***.com/questions/3470098/…的可能重复 【参考方案1】:

另一种 LINQ 方法:

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

【讨论】:

我个人的经验是,Linq 的性能总体上比很多人想象的要好得多,在大多数情况下,它最终只是执行与其他代码相同的操作的语法糖,所以你通常不会感到不同。实际上,对于这种特殊情况,我只知道它有效,我想如果它表现不佳,那么你将不得不选择一个完全不同的数据结构,因为这个完整的列表连接总是需要一些时间,不管你怎么做。 【参考方案2】:

一种方法:

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

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

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

【讨论】:

您假设对于订单列表中的每个 int,项目列表中都会存在一个对应的 Item... order.Where(d.ContainsKey).Select(...) 或 Select/SelectMany 具有更长的函数,使用 TryGetValue 解决了这个问题。【参考方案3】:

不是这个确切问题的答案,但如果您有两个数组,则Array.Sort 的重载需要数组进行排序,还有一个数组用作“钥匙”

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

Array.Sort 方法(Array, Array) 对一对一维 Array 对象进行排序(一个包含键 另一个包含相应的项目)基于中的键 第一个数组使用每个键的 IComparable 实现。

【讨论】:

知道如何使它适用于列表吗?我在这里因为我必须使用列表并且不能使用这个漂亮的数组排序东西。【参考方案4】:

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

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

非常易读。

【讨论】:

重要提示:这需要首先对ints 列表进行排序。接受的答案没有。 @Thorarin 不,我认为。你为什么这么说?无论如何,我们对ints 进行排序以获得排序顺序,因此不必首先对整数进行排序。 @Thorarin,那么还有其他问题。我确信我的代码:) 它绝对不能解决OP描述的问题。您的代码从未真正评估对象的 ID 属性。它怎么可能把东西按正确的顺序排列? @Thorarin 我在回答中明确表示Join 解决了一种问题。 Zip 用于其他用途。标题是“按另一个集合的顺序对集合进行排序”,对于绝大多数人来说,它暗示了我在答案中所追求的。我刚刚留下了一个替代答案,可能会帮助将来遇到类似问题的人。当然,如果排序是基于 id 的,那么还必须指定适当的比较器(在 OrderBy 中)【参考方案5】:

这是一个扩展方法,它为任何类型的列表封装了Simon D.'s response。

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

【讨论】:

【参考方案6】:

一种可能的解决方案:

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

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

【讨论】:

【参考方案7】:

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

【讨论】:

请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。

以上是关于将一个列表按另一个排序的主要内容,如果未能解决你的问题,请参考以下文章

按另一个具有重复项的列表对列表进行排序

按属性排序列表,然后按另一个

Java按整数字段对对象数组进行排序,如果它们相同,则按另一个整数值排序

按另一个数组排序数组?

按一个变量排序,按另一个分组,然后在 R 中的 SQL Query 中选择第一行

如何在Scala中按另一个列表拆分列表