2

我有列表,我想要一种简短而快速的方法来将其中一个元素作为第一个元素。我想使用下面的代码来选择第 10 个元素并首先创建它。但寻找更好的解决方案

tempList.Insert(0, tempList[10]);
tempList.RemoveAt(11);
4

2 回答 2

3

如果您不介意其余的顺序,您实际上可以交换位置 0 和 10 的两个项目,相信这比插入和删除更好:

var other = tempList[0];
tempList[0]=tempList[10];
tempList[10] = other;

您甚至可以将其作为 List 的扩展以方便使用,例如:

 public static void Swap<T>(this List<T> list, int oldIndex, int newIndex)
 { 
      // place the swap code here
 }
于 2013-08-06T06:58:50.160 回答
0

在某些特殊情况下,您可以获得更好的性能(为了简单起见,我假设该值始终插入到它的位置之前):

class Program
{
    const int Loops = 10000;
    const int TakeLoops = 10;
    const int ItemsCount = 100000;
    const int Multiplier = 500;
    const int InsertAt = 0;

    static void Main(string[] args)
    {
        var tempList = new List<int>();
        var tempDict = new Dictionary<int, int>();
        for (int i = 0; i < ItemsCount; i++)
        {
            tempList.Add(i);
            tempDict.Add(i, i);
        }

        var limit = 0;
        Stopwatch
            sG = new Stopwatch(),
            s1 = new Stopwatch(),
            s2 = new Stopwatch();
        TimeSpan
            t1 = new TimeSpan(),
            t2 = new TimeSpan();

        for (int k = 0; k < TakeLoops; k++)
        {
            var takeFrom = k * Multiplier + InsertAt;
            s1.Restart();
            for (int i = 0; i < Loops; i++)
            {
                tempList.Insert(InsertAt, tempList[takeFrom]);
                tempList.RemoveAt(takeFrom + 1);
            }
            s1.Stop();
            t1 += s1.Elapsed;
            s2.Restart();
            for (int i = 0; i < Loops; i++)
            {
                var e = tempDict[takeFrom];
                for (int j = takeFrom - InsertAt; j > InsertAt; j--)
                {
                    tempDict[InsertAt + j] = tempDict[InsertAt + j - 1];
                }
                tempDict[InsertAt] = e;
            }
            s2.Stop();
            t2 += s2.Elapsed;
            if (s2.Elapsed > s1.Elapsed || limit == 0)
                limit = takeFrom;
        }

        sG.Start();
        for (int k = 0; k < TakeLoops; k++)
        {
            var takeFrom = k * Multiplier + InsertAt;
            if (takeFrom >= limit)
            {
                for (int i = 0; i < Loops; i++)
                {
                    tempList.Insert(InsertAt, tempList[takeFrom]);
                    tempList.RemoveAt(takeFrom + 1);
                }
            }
            else
            {
                for (int i = 0; i < Loops; i++)
                {
                    var e = tempDict[takeFrom];
                    for (int j = takeFrom - InsertAt; j > InsertAt; j--)
                    {
                        tempDict[InsertAt + j] = tempDict[InsertAt + j - 1];
                    }
                    tempDict[InsertAt] = e;
                }
            }
        }
        sG.Stop();
        Console.WriteLine("List:       {0}", t1);
        Console.WriteLine("Dictionary: {0}", t2);
        Console.WriteLine("Optimized:  {0}", sG.Elapsed);

        /***************************
        List:       00:00:11.9061505
        Dictionary: 00:00:08.9502043
        Optimized:  00:00:08.2504321
        ****************************/
    }
}

在上面的示例中,aDictionary<int,int>用于存储每个元素的索引。insertAt如果和之间的差距takeFrom更小,您将获得更好的结果。随着此间隔的增加,性能将下降。我猜你可能想评估这个差距并根据它的价值选择最佳分支。

于 2013-08-06T07:37:19.903 回答