【问题标题】:List set index c#列表集索引 c#
【发布时间】:2010-08-22 22:24:56
【问题描述】:

我正在使用 List 构造来处理在“OnPaint”中绘制图像的顺序。现在,如果我的图像被重新排序(例如“带到前面”或“.. 到后面”),我需要在我的列表中重新定位它们。 我这样做有困难,因为 List 不支持类似于 setIndex() 的方法。

所以我想做的基本上是:

    private List<BitmapWithProps> activeImages = new List<BitmapWithProps>();

    public void addActiveImage(BitmapWithProps image)
    {
        activeImages.Add(image);
    }

    public BitmapWithProps getActiveImage(int index)
    {
        return activeImages[index];
    }

    public void removeActiveImage(int index)
    {
        activeImages.RemoveAt(index);
    }

    public void removeActiveImage(BitmapWithProps item)
    {
        activeImages.Remove(item);
    }

    public void swapActiveImageIndex(int sourceIndex, int destIndex)
    {
        // what would the code look like in here if I were to swap
        // the 2nd item (1) with the 4th one (3) in a 5-item-List (0 - 4)
    }

我希望能够交换索引.. 有点。我可以在它应该去的索引处将一个新项目“插入”到列表中并分配值,然后删除另一个“源”。然而,它看起来并不优雅。

我很乐意提供任何提示,如果我忽略了一个线程,请原谅 - 我在询问之前进行了搜索。

dS.

【问题讨论】:

    标签: c# arrays list


    【解决方案1】:

    执行您想做的步骤有什么不雅点?如果您想更改某个列表(这是一个矢量样式集合)中的某个位置,那么您想要 将其插入到新位置并从旧位置中删除。正是您抱怨必须做的事情。

    如果真的让你不高兴,那就写一个扩展方法:

    public static void MoveIndex<T>(this List<T> list, int srcIdx, int destIdx)
    {
      if(srcIdx != destIdx)
      {
        list.Insert(destIdx, list[srcIdx]);
        list.RemoveAt(destIdx < srcIdx ? srcIdx + 1 : srcIdx);
      }
    }
    

    编辑:哦,你只是想交换?更简单(更高效):

    public static void SwapItems<T>(this List<T> list, int idxX, int idxY)
    {
      if(idxX != idxY)
      {
        T tmp = list[idxX];
        list[idxX] = list[idxY];
        list[idxY] = tmp;
      }
    }
    

    【讨论】:

    • 谢谢。我实际上已经考虑过插入/删除,但我认为有更好的方法,比如真的..交换什么的。另一方面 - 你的方法正是我想做的。现在我只需要弄清楚如何将此方法添加为列表的扩展:)。谢谢+投票。
    • 我也添加了交换如果这些方法被放在调用代码“可见”的静态类中,那么 activeImages.MoveIndex(1, 3)activeImages.SwapItems(1, 3) 将在 C#3 或更高版本中执行适当的操作. C#2 或更低版本,您需要摆脱“this”并将它们作为静态方法调用,或者只执行与方法相同的操作。
    • 请注意,应首选交换方法,因为它是 O(1),而 List.Insert 和 List.RemoveAt 都是 O(n)。他们可能必须上下移动列表中的剩余元素,以保持直接列表的明确定义(但您实际上只关心最终结果)。
    • 啊。感谢这个提示,Gnafoo。这就是我寻求帮助的原因,因为否则我可能已经实现了一个实际有效但不“优雅”的方法,因此需要更多时间来完成。
    • 是的,在适当的地方交换节拍。但是,如果不合适(您将第一项移动到第四个位置),那么通过一系列交换来做到这一点也是 O(n) 虽然对于较小的 n,并且具有更昂贵的常量,所以我会选择直接方法除非列表可能非常大,或者循环移动。
    【解决方案2】:

    好吧,执行交换很简单:

    BitmapWithProps source = activeImages[sourceIndex];
    BitmapWithProps dest = activeImages[destIndex];
    activeImages[destIndex] = source;
    activeImages[sourceIndex] = dest;
    

    但是如果您需要移动一个项目并让所有其他项目以相同的顺序相互关联,您应该调用RemoveAt,然后调用Insert。它不会非常有效,但是除非您有一个很大的列表或者您经常这样做非常,否则它不太可能真的给您带来任何问题。

    【讨论】:

      【解决方案3】:
      public void swapActiveImageIndex(int sourceIndex, int destIndex)
      {
          var source = activeImages.Item[sourceIndex];
          var dest = activeImages.Item[destIndex];
      
          activeImages.Item[sourceIndex] = dest;
          activeImages.Item[destIndex] = source;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-02
        • 1970-01-01
        • 2011-08-26
        • 1970-01-01
        • 2010-10-17
        • 1970-01-01
        • 2012-12-30
        • 2019-07-06
        相关资源
        最近更新 更多