2009-01-20 168 views
1

这可能是一个简单的问题。假设我有一个大约20-50个条目左右的小列表。例如:什么是插入列表中间的东西的好方法?

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

stored in something like 
List<Item> 

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

比方说,我想将Item.OrderNumber = 30移动到Item.OrderNumber = 20或类似的地方。当我这样做的时候,现在需要改变20以上的所有东西,以便旧的20现在是21,21现在是22等,直到我将它设置为30.它还需要以另一种方式进行,所以当Item.OrderNumber = 30移至Item.OrderNumber = 34,所有内容都必须向下移动。

我在考虑冒泡列表几次,但我希望有更好的方法来做到这一点。虽然列表大小很小,但对于各种不同的事情,这需要做很多工作。

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

回答

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; 
    } 
} 
0

如果使用双链表,可以做ORDERNUMBER = 30的非常廉价的插入位置19后或20之前接着迭代,以小于30 ORDERNUMBER和通过增加各顺序1.在列表中移动一个更高的项目。

2

是否必须是List<T>?如果不是,您可以考虑使用SortedList<TKey, TValue>SortedDictionary<TKey, TValue>。然后,您可以使用OrderNumber作为关键字,并让集合完成工作。

Alterantively,为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中所建议的。

+0

是List .BinarySearch到跳跃列表IMPL的接口? – mabbit 2009-01-20 07:01:52

+0

这仅仅是一个由数组支持的列表上的普通二分查找。 – 2009-01-20 07:08:58

0

只需在填充列表后进行排序,然后通过在最后粘贴东西来填充。如果您需要随时分类,请执行Skeet所说的事情。

1

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

这可以通过包装清单,并实现自己的操作(移动/插入/删除功能,做了以下来完成:通过所有的项目

插入 环和一个地方增加订单号码该订单号码> =新项目的订单号 的项目添加到列表中

删除 通过所有的项目中删除项目 环路和1减少订单号码,其中订单号码>已删除项目的订单号

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

相关问题