重新排序位置项列表

时间:2008-10-27 08:02:53

标签: c#

我有一个Request对象,其中包含一个Approvers列表。审批人有名称和批准职位。

  1. 马修
  2. 马克
  3. 卢克
  4. 约翰
  5. 最终,一个请求将从Mathew开始,并以John结束。

    我需要能够重新订购这些允许添加和删除的内容,如下所述。

    批准者可以是 -

    在某个位置添加 - 即。在第3位添加Peter,在这种情况下,新订单将是

    1. 马修
    2. 马克
    3. 彼得
    4. 卢克
    5. 约翰
    6. 删除 - 即。删除标记,在这种情况下新订单是

      1. 马修
      2. 卢克
      3. 约翰
      4. 已编辑 - 即您可以将John的位置更改为1,在这种情况下,新订单为

        1. 约翰
        2. 马修
        3. 马克
        4. 卢克
        5. 我已经提出了许多解决方案,但是没有一个是特别优雅的。

          非常感谢任何帮助

2 个答案:

答案 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);
        }
    }
}