【问题标题】:How do I swap 2 elements in a list [duplicate]如何交换列表中的 2 个元素 [重复]
【发布时间】:2012-07-01 15:01:23
【问题描述】:

可能重复:
Swap two items in List<T>

编辑:也许这对获取 'b' 值有用?

for (int i = 0; i < inventory.Count; i++)
{
    if (inventory[a].ItemRectangle.Intersects(inventory[i].ItemRectangle))
    {
        itemB = inventory[i];
    }
}

编辑:这是我的进度。

Item itemA;
Item itemB;

int a = -1;
int b = -1;

if (a != -1 && b != -1)
{
    itemA = inventory[a];
    itemB = inventory[b];

    Swap(ref itemA, ref itemB);

    inventory[a] = itemA;
    inventory[b] = itemB;
}

这就是我得到“a”值的地方。

if (item.ItemSelected == true)
{
    a = item.ItemIndex;
}
else
    a = -1;

我还没有弄清楚如何获得“b”值,因为我必须检查一个项目是否与同一个列表中的另一个项目发生冲突。如果有人知道我该怎么做,请告诉我。我猜它看起来像这样:

if (item.ItemRectangle.Intersects(//the other item.ItemRectangle)
{
    b = item.ItemIndex;
}
else
    b = -1;

我已经创建了一个列表,名为inventory。所以现在我想实现一个交换功能,像这样:

foreach (Item item in inventory)
{
    if (mouseRectangle.Intersects(item.ItemRectangle))
    {
        if (Input.EdgeDetectLeftMouseDown())
        {
            switch (item.ItemSelected)
            {
                case false:
                    item.ItemSelected = true;
                    break;
                case true:
                    item.ItemSelected = false;
                    break;
            }
        }  
    }
    else if (Input.EdgeDetectLeftMouseDown())
    {
        switch (item.ItemSelected)
        {
            case true:
                item.ItemSelected = false;
                break;
        }
    }
    else if (item.ItemSelected == true)
    {
        item.ItemPosition = new Vector2(mouseRectangle.X, mouseRectangle.Y);
        item.ItemRectangle = new Rectangle(mouseRectangle.X, mouseRectangle.Y, 32, 32);
    }
    else if (item.ItemSelected == false && //a lot of checks to determine it is not intersecting with an equip slot
    {
        item.ItemPosition = item.OriginItemPosition;
        item.ItemRectangle = item.OriginItemRectangle;
    }
    else if (item.ItemRectangle.Intersects(item.ItemRectangle))
    {
        //SwapItem(inventory, item, item);
    }

这就是我需要帮助的代码部分。我希望列表中的任何项目都能够与列表中的任何其他项目交换。我的 SwapItem 方法只是一个占位符,我实际上还没有 SwapItem 方法。

我希望您传递给方法的参数与我要交换的项目相关。所以第一个项目是我用鼠标选择的项目,另一个项目应该是第一个项目与之相交的项目。

【问题讨论】:

  • 去学习C#语言,然后回来,你会得到帮助。我很清楚你不了解编程的基础知识,for 循环应该是你学习的第一件事。我建议你先学习 C++,这样你就可以理解编程的基础知识,并用 C# 等高级语言高效地编程,但这取决于你。
  • 首先,我知道我问这么多很烦人。但这就是我来这里学习的原因。而且我确实知道 for 循环是什么,我只是不明白为什么我需要它。我的 a 和 b 值除了 -1 之外的唯一值是当我选择了一个项目并单击另一个项目时。这样它将通过 if 检查并交换项目。老实说,我看不出我在这里做错了什么。我唯一遇到的问题是获取 b 值,因为我必须检查同一列表中两个项目之间的冲突。
  • 再看我的回答,我编辑了,希望你能理解。
  • 我现在应该有足够的信息来解决这个问题,无论是我自己的方法还是你的方法。非常感谢您的帮助。
  • 您的方法运行良好,但与 foreach 不同,它滞后很多。所以我将不得不使用foreach。但它应该可以工作。

标签: c# list xna swap


【解决方案1】:

要交换列表中的元素,您可以编写 extension method 为。

public static class ExtensionMethods
{
    public static void Swap<T>(this List<T> list, int index1, int index2)
    {
         T temp = list[index1];
         list[index1] = list[index2];
         list[index2] = temp;
    }
}

请记住将扩展方法放在静态类中。

那么你可以这样做:

yourList.Swap(0,1); // swap element at index 0 with element at index 1

【讨论】:

  • +1 使用扩展方法!
  • 当你必须声明 ExtensionMethods.Swap 时,你怎么能这样声明 .Swap...
  • @Obsivus,我不太确定你的问题,你是想问Extension method works 怎么样?
  • Nvm 我想错了,对不起。会回答:)它工作得很好
  • @Obsivus,我不知道你是如何使用它的。在公共静态类中声明它,然后应该可以使用List&lt;T&gt;
【解决方案2】:

要交换两个变量的值,最简单的方法是使用引用。这是一个经典的 C++ 指针练习,但它也适用于 C#。

// Replace int with any data type / class you need
void Swap (ref int a, ref int b)
{
   int c = a; 
   a = b; 
   b = c;
}

使用的算法很简单,解释通常是这样的:你有两个杯子,一个是水的,一个是油的。要将油放入第一个玻璃杯中,您需要使用第三个玻璃杯,将水放入其中,然后将油放入第一个玻璃杯中,再将水放入第二个玻璃杯中。


这就是我的想法。寻找 cmets,以便您了解发生了什么。:

// Unlike foreach, with for I can change the values in the list
for (int i = 0; i < inventory.Count; i++)
{
    if (mouseRectangle.Intersects(inventory[i].ItemRectangle))
    {
        if (Input.EdgeDetectLeftMouseDown())
        {
            // You can replace the switch with this shorter structure
            // if A is a bool value, !A will have the opposite value
            inventory[i].ItemSelected = !inventory[i].ItemSelected;
        }  
    }
    else if (Input.EdgeDetectLeftMouseDown())
    {
        // You don't need a case-switch for a single condition. An if should suffice
        if (inventory[i].ItemSelected) 
            inventory[i].ItemSelected = false;
    }
    else if (inventory[i].ItemSelected == true)
    {
        inventory[i].ItemPosition = new Vector2(mouseRectangle.X, mouseRectangle.Y);
        inventory[i].ItemRectangle = new Rectangle(mouseRectangle.X, mouseRectangle.Y, 32, 32);
    }
    else if (inventory[i].ItemSelected == false && //a lot of checks to determine it is not intersecting with an equip slot
    {
        inventory[i].ItemPosition = inventory[i].OriginItemPosition;
        inventory[i].ItemRectangle = inventory[i].OriginItemRectangle;
    }

    // Something definitely wrong with this line, a rectangle to instersect with itself??
    else if (inventory[i].ItemRectangle.Intersects(inventory[PROBABLY_SOMETHING_ELSE].ItemRectangle))
    {
        Swap (ref inventory[i], ref inventory[PROBABLY_SOMETHING_ELSE])
    }
}

【讨论】:

  • 嗯...你想交换什么? Inventory好像是容器,示例代码中其他参数是item和item,是一回事……
  • 我不明白的是你想用'item'替换'item',你想用它自己交换一个对象吗?要修复该错误,您可以将 foreach 替换为 for,并使用索引值进行迭代。您还需要将 item 替换为 inventory[index]...
  • 不,'item' 会在整个代码块中保留它的值,然后将其更改为列表中的下一个值,在整个代码块中再次保留它等等。我认为您想交换列表中具有不同索引的两个项目,因此您需要进行我告诉您的替换。
  • 是的,但我不希望这些索引被“硬编码”。索引 a = 我正在选择的项目。索引 b = 项目 a 正在与之碰撞的项目。
  • 没错,为什么不创建两个具有这些值的变量 a 和 b,然后将 inventory[a] 与 inventory[b] 交换呢?您还需要将 foreach 替换为 for,因为在使用 foreach 循环时无法修改列表中的值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
相关资源
最近更新 更多