对位置项列表重新排序

本文关键字:排序 新排序 位置 列表 | 更新日期: 2023-09-27 17:47:23

我有一个包含审批者列表的请求对象。审批者具有名称和审批职位。

  1. 马修
  2. 马克
  3. 卢克
  4. John

最终,请求将通过这个链,从马修开始,到约翰结束。

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

审批者可以是 -

添加到某个位置 - 即。在位置 3 添加 Peter,在这种情况下,新顺序将是

  1. 马修
  2. 马克
  3. 彼得
  4. 卢克
  5. John

删除 - 即。删除标记,在这种情况下,新订单是

  1. 马修
  2. 卢克
  3. John

已编辑 - 即您可以将 John 的位置更改为 1,在这种情况下,新订单为

  1. John
  2. 马修
  3. 马克
  4. 卢克

我已经提出了许多解决方案,但没有一个是特别优雅的。

任何帮助将不胜感激

对位置项列表重新排序

列表可能有多大? 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);
        }
    }
}