Reordering items which must have alphabetically ordered keys I have a list of objects each with a unique Key and a display name (Label). The list needs to remain sorted by the keys of each object but unfortunately the keys need to be strings rather than numerical and as such 'sorted' here refers to the keys being sorted alphabetically rather than numerically. (Although the keys can be string of numbers - their actual string values don't matter so long as they're alphabetically ordered).

The list should be re-order-able but then the keys need to re-shuffle so that they're once more in alphabetical order.

Currently my implementation allows for the re-ordering of the list and then iterates over all of the objects re-assigning them fresh keys in alphabetical order - something which I feel is a bad idea as it's a lot of effort for a single swap of values.

My object looks like the following

class Item
{
    public string Key { get; set; }
    public string Label { get; set; }

    public Item(string key, string label)
    {
        Key = key;
        Label = label;
    }

    public override string ToString() =&gt; Key + ", " + Label;
}


I have added an extension method to handle the re-ordering process

static class Utils
{
    public static List&lt;Item&gt; MoveIndex(this List&lt;Item&gt; myItems, int from, int to)
    {
        Item temp = myItems[from];
        myItems.RemoveAt(from);
        myItems.Insert(to, temp);

        for (int i = 0; i &lt; myItems.Count; i++)
        {
            myItems[i].Key = i.ToString("D2");
        }

        return myItems;
    }
}


And finally I have an example usage of the extension method

static void Main(string[] args)
{
    List&lt;Item&gt; myItems = new List&lt;Item&gt;()
    {
        new Item("0", "Zero"),
        new Item("1", "One"),
        new Item("2", "Two"),
        new Item("3", "Three"),
        new Item("4", "Four"),
        new Item("5", "Five"),
        new Item("6", "Six"),
        new Item("7", "Seven"),
        new Item("8", "Eight"),
        new Item("9", "Nine"),
        new Item("10", "Ten"),
        new Item("11", "Eleven"),
        new Item("12", "Twelve"),
    };

    myItems.MoveIndex(3, 5);

    Console.ReadKey();
}


As the code currently sits, placing a breakpoint on the Console.ReadKey() shows that the Labels are not in their original order but the Keys are - proving that it currently works.



Are there any better ways to manage the Keys when the list is being re-ordered? Perhaps ways which don't require iterating over everything in the list?

Are there any better strings which I could be using for the keys?



I know that as it sits this system has a capacity for only 100 Items before it breaks and that is OK - There will be checking in place to ensure that there are never more than this.
public static List&lt;Item&gt; MoveIndex(this List&lt;Item&gt; myItems, int from, int to)



Code to the interface, not the implementation: you might be able to rewrite this as

    public static IList&lt;Item&gt; MoveIndex(this IList&lt;Item&gt; myItems, int from, int to)


and if not you can almost certainly rewrite it as

    public static TList MoveIndex&lt;TList&gt;(this TList myItems, int from, int to)
        where TList : IList&lt;Item&gt;





        for (int i = 0; i &lt; myItems.Count; i++)
        {
            myItems[i].Key = i.ToString("D2");
        }



For a start, this looks too tightly bound to me. From the description given I would expect MoveIndex to work with the existing keys, whatever they are.

But given the strong assumptions made here, I wonder whether there's a better solution based on eliminating the List&lt;Item&gt; entirely. Can you maintain an IList&lt;string&gt; which contains the labels and then generate the items lazily with IEnumerable&lt;string&gt;.Select(Func&lt;string, int, Item&gt;)?