对位置项列表重新排序
本文关键字:排序 新排序 位置 列表 | 更新日期: 2023-09-27 17:47:23
我有一个包含审批者列表的请求对象。审批者具有名称和审批职位。
- 马修
- 马克
- 卢克
- John
最终,请求将通过这个链,从马修开始,到约翰结束。
我需要能够重新排序这些允许添加和删除的内容,如下所述。
审批者可以是 -
添加到某个位置 - 即。在位置 3 添加 Peter,在这种情况下,新顺序将是
- 马修
- 马克
- 彼得
- 卢克
- John
删除 - 即。删除标记,在这种情况下,新订单是
- 马修
- 卢克
- John
已编辑 - 即您可以将 John 的位置更改为 1,在这种情况下,新订单为
- John
- 马修
- 马克
- 卢克
我已经提出了许多解决方案,但没有一个是特别优雅的。
任何帮助将不胜感激
列表可能有多大? List<T>
可能是集合的最简单表示形式,但这意味着每次插入列表中间或从列表中删除时都需要一个副本。"编辑"列表基本上意味着删除/插入。
然后,迭代就很简单了。
另一种选择可能是LinkedList<T>
- 如果您坚持与每个审批者关联的LinkedListNode<T>
,它使迭代变得简单,并且"在之后插入","在之前插入"和"删除"便宜。但是说"这个审阅者现在应该在位置 3"并不容易 - 你必须迭代才能首先找到位置 3(或 2,无论如何)。如果是"在此审批者之后移动此审批者"的情况,那么这是理想的情况。
维护位置属性是一种痛苦,因为您需要进行大量修改才能更改某些内容(同时保持一切逻辑)。这也使得难以有效地序列化/反序列化。
您不能简单地从List<T>
或类似位置推断位置吗?然后你可以Add()
到最后,Insert()
到中间,从任何地方Remove()
。要移动某些东西,您只需将其Remove()
并将其Insert()
到您想要的位置即可?
像这样(格式化为空格):
using System;
using System.Collections.ObjectModel;
using System.Linq;
// I only added this to use a lazier "collection initializer" below,
// which needs an Add(string) method...
class ApproverCollection : Collection<Approver> {
public void Add(string name) { Add(new Approver(name)); }
}
class Request {
public Request() { Approvers = new ApproverCollection(); }
public ApproverCollection Approvers { get; private set; }
}
class Approver {
public Approver(string name) { Name = name; }
public string Name { get; set; }
}
static class Program {
static void Main() {
Request req = new Request {
Approvers = {"Mathew", "Mark", "Luke", "John"}
};
req.ShowState("Initial");
req.Approvers.Insert(2, new Approver("Peter"));
req.ShowState("Inserted Peter");
Approver mark = req.Approvers.Single(x => x.Name == "Mark");
req.Approvers.Remove(mark);
req.ShowState("Removed Mark");
Approver john = req.Approvers.Single(x => x.Name == "John");
req.Approvers.Remove(john);
req.Approvers.Insert(0, john);
req.ShowState("Moved John");
}
static void ShowState(this Request request, string caption) {
Console.WriteLine();
Console.WriteLine(caption);
int pos = 1;
foreach(Approver a in request.Approvers) {
Console.WriteLine("{0}: {1}", pos++, a.Name);
}
}
}