我有一个Request对象,其中包含一个Approvers列表。审批人有名称和批准职位。
最终,一个请求将从Mathew开始,并以John结束。
我需要能够重新订购这些允许添加和删除的内容,如下所述。
批准者可以是 -
在某个位置添加 - 即。在第3位添加Peter,在这种情况下,新订单将是
删除 - 即。删除标记,在这种情况下新订单是
已编辑 - 即您可以将John的位置更改为1,在这种情况下,新订单为
我已经提出了许多解决方案,但是没有一个是特别优雅的。
非常感谢任何帮助
答案 0 :(得分:5)
这些名单可能有多大? List<T>
可能是集合中最简单的表示形式,但这意味着每次插入或从列表中间删除时都需要复制。 “编辑”列表基本上意味着删除/插入。
迭代很简单。
替代方案可能是LinkedList<T>
- 这会使迭代变得简单,“插入之后”,“插入之前”和“删除”便宜的如果挂起LinkedListNode<T>
关联与每个批准者。但是这并不容易说“这个评论者现在应该在第3位” - 你必须先迭代才能找到第3位(或者2位,无论如何)。如果这是“在此之后移动此批准者”的情况,那么这是理想的。
答案 1 :(得分:4)
维护位置属性是一件痛苦的事情,因为您需要进行大量修改才能更改某些内容(同时保持一切合乎逻辑)。它也使得很难有效地序列化/反序列化。
你能不能简单地从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);
}
}
}