1

这大概是一个简单的问题。假设我有一个包含大约 20-50 个条目的小列表。就像是:

class Item
{
   int ItemNumber;
   int OrderNumber;
   string Name;
}

stored in something like
List<Item>

这存储在通用列表或数组中,OrderNumber 从 1、2、3、4、....50 开始。为了使事情变得更容易,我们假设 OrderNumber 已经在 List 中的其他地方通过 QuickSort 进行了排序(除非这使事情变得更复杂)。

假设我想将 Item.OrderNumber = 30 移动到 Item.OrderNumber = 20 或类似的位置。当我这样做时,现在需要移动 20 以上的所有内容,以便旧的 20 现在是 21,21 现在是 22,等等,直到我达到 30。它还需要以其他方式进行,所以当 Item.OrderNumber = 30被移动到 Item.OrderNumber = 34 并且一切都必须向下移动。

我正在考虑将列表冒泡几次,但我希望有更好的方法来做到这一点。尽管列表大小很小,但这需要为各种不同的事情做很多事情。

编辑:只是为了让你知道。结果最终必须以某种类型的事务存储在数据库中。

4

5 回答 5

2

它必须是一个List<T>吗?如果没有,您可以考虑使用 aSortedList<TKey, TValue>或 a SortedDictionary<TKey, TValue>。然后,您可以使用 OrderNumber 作为键,让集合完成工作。

或者,List<T>您可以使用按订单号进行比较List<T>.BinarySearch的适当IComparer<T>的 - 您将拥有:

int position = list.BinarySearch(newOrder, orderComparer);
list.Insert(position >= 0 ? position : ~position, newOrder);

IComparer<T>您可以在整个代码中使用相同的实例,因为它是无状态的。

编辑:此解决方案不会更改任何其他条目的 OrderNumber,如Robert Wagner's answer中所建议的那样。

于 2009-01-20T06:21:56.197 回答
1

如果我理解正确,您正试图将 OrderNumber 保留在对象内(无论出于何种原因),但需要能够向列表中添加一个新对象并让所有其他对象调整它们的 OrderNumber 以使新对象适合。此外,列表中项目的实际顺序(不一定)无关紧要。

这可以通过包装列表并实现您自己的操作来完成(移动/插入/删除函数,它执行以下操作:

Insert 循环遍历所有项目并将订单号加一,其中订单号 >= 新项目的订单号 将项目添加到列表

删除 删除项目 循环遍历所有项目并将订单号减一,其中订单号 > 已删除项目的订单号

移动 移除项目 重新编号项目 插入项目

于 2009-01-20T07:24:09.627 回答
0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Class1
{                     
    static void Main()
    {
        var beatles = new LinkedList<string>();

        beatles.AddFirst("John");                        
        LinkedListNode<string> nextBeatles = beatles.AddAfter(beatles.First, "Paul");
        nextBeatles = beatles.AddAfter(nextBeatles, "George");
        beatles.AddAfter(nextBeatles, "Ringo");


        LinkedListNode<string> paulsNode = beatles.NodeAt(1); // middle's index
        LinkedListNode<string> recentHindrance = beatles.AddBefore(paulsNode, "Yoko");
        recentHindrance = beatles.AddBefore(recentHindrance, "Aunt Mimi");
        beatles.AddBefore(recentHindrance, "Father Jim");


        Console.WriteLine("{0}", string.Join("\n", beatles.ToArray()));

        Console.ReadLine();                       
    }
}

public static class Helper
{
    public static LinkedListNode<T> NodeAt<T>(this LinkedList<T> l, int index)
    {
        LinkedListNode<T> x = l.First;

        while ((index--) > 0) x = x.Next;

        return x;
    }
}
于 2009-01-20T05:49:57.073 回答
0

如果您使用双链表,您可以非常便宜地将 OrderNumber = 30 插入 19 之后或 20 之前的位置。然后迭代到小于 30 的 OrderNumber 并将每个订单增加 1。然后对在列表中上移一个项目。

于 2009-01-20T05:52:04.277 回答
0

只需在填充列表后进行排序,然后通过在最后粘贴东西来填充。如果您需要始终对其进行分类,请按照 Skeet 所说的做。

于 2009-01-20T06:58:59.757 回答