c# - 在另一个列表中创建按顺序排序的排序列表
问题描述
我有一个已按优先级排序的项目列表,以及一组未排序的项目。每个未排序的项目可能会或可能不会出现在优先列表中。
如何创建一个新列表,其中仅包含优先列表中出现的未排序项目,按照它们出现在优先列表中的顺序?
例如
List<Foo> priorityList = GetPriorityList();
IEnumerable<Foo> unsorteditems = GetSomeItems();
List<Foo> prioritisedItems = new List<Foo>();
foreach (var item in unsorteditems)
{
if (priorityList.Contains(item))
{
//Add item to prioritisedItems in the order it appears in priorityList
}
}
粗略的实现很容易,但看起来很混乱且效率低下:
List<Foo> sortedList = new List<Foo>();
foreach (var item in unsortedItems)
{
if (priorityList.Contains(item) && !sortedList.Contains(item))
{
if (sortedList.Count() < 1)
{
sortedList.Add(item);
}
else
{
foreach (var sortedItem in sortedList)
{
if (priorityList.IndexOf(sortedItem) < priorityList.IndexOf(item))
{
sortedList.Insert(sortedList.IndexOf(sortedItem), item);
break;
}
}
}
}
}
有没有更清洁的方法来做到这一点?
关于这个主题的其他问题似乎 a) 使用要排序的项目的属性,或 b) 假设所有未排序的项目将出现在已经排序的列表中。
编辑:
根据要求,在这种特定情况下,这是 Foo 对象:
public partial class Erpstatuscodes
{
public string ProgramCode { get; set; }
public string StatusCode { get; set; }
public string StatusCodeDescription { get; set; }
public string ShortDescription { get; set; }
public string TestInstructions { get; set; }
public string SampleType { get; set; }
public string StatusType { get; set; }
}
unsortedItems 将从 EntityFramework 中提取,但 priorityList 项将从配置文件中反序列化。
此外,为了澄清,这是使用 .NET Framework 4.8,而不是 .NET Core。
解决方案
你说Foo
没有任何成员可以与之比较,所以我假设那Foo
是一个class
(不是 a struct
)并且你依赖于对象引用相等(==
或Object.ReferenceEquals
)),这就是你的priorityList.IndexOf(sortedItem)
代码在 - 下所做的-hood,下面的代码应该在其中工作:
Dictionary<Foo,Int32> priorityListIndexes = priorityList
.Select( ( foo, idx ) => ( foo, idx ) )
.ToDictionary( t => t.foo, t => t.idx);
List<Foo> prioritisedItems = unsorteditems
.Select( unsortedFoo => ( foo: unsortedFoo, ok: priorityListIndexes.TryGetValue( unsortedFoo, out Int32 idx ), idx: idx ) )
.Where( t => t.ok )
.OrderBy( t => t.idx )
.Select( t => t.foo )
.ToList();
请注意,一般来说,对 使用引用类型是个坏主意TKey
,但在这种情况下,没关系。
这实际上可以简化为单个.Join
(同样需要注意Foo
的是,连接谓词可以接受引用相等):
List<Foo> prioritisedItems = Enumerable
.Join<Foo>(
outer : priorityList.Select( ( foo, idx ) => ( foo, idx ) ),
inner : unsorteditems,
outerKeySelector: t => t.foo,
innerKeySelector: foo => foo,
resultSelector : ( left, right ) => ( left.idx, right )
)
.OrderBy( t => t.idx )
.Select( t => t.foo )
.ToList();
推荐阅读
- python - 如何使 geopandas 地图共享 x 和 y 轴?
- apache-spark - 从文件中读取数据时触发“modifiedBefore”选项
- honeypot - honeywall roo 1.4 错过了 honeywall.conf 文件
- python - 在python中等待docker容器重启
- java - 在 Spring Batch 应用程序中使用 BufferWriter 处理回滚
- javascript - 如何使用javascript将新数组的第一个数字添加到它之前的数组中以获得总和
- c# - 如何在 Xamarin Forms 应用程序中翻译来自 API 的数据
- android - 使用 SQLCipher 后我的 SQLite 数据库是否安全?
- r - 选择输入启用或禁用操作按钮 - 有问题
- python - 如何修复代码而不在 python 中再次计算相同的元素?