¿Cómo intercambio 2 elementos en una lista [duplicado]

Posible duplicado:
Intercambiar dos elementos en la Lista

Editar: ¿Tal vez esto funcione para obtener el valor 'b'?

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

Editar: Aquí está mi progreso.

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

Y aquí es donde obtengo el valor 'a'.

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

No he descubierto cómo obtener el valor 'b' porque tendría que buscar un elemento que colisione con otro elemento que esté en la misma lista. Si alguien sabe cómo puedo hacer esto, por favor dígame. Se vería algo como esto, supongo:

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

Hice una Lista < Artículo > llamada inventario. Entonces ahora quiero implementar una función de intercambio, como esta:

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

Esa es la parte del código con la que necesito ayuda. Quiero que cualquier elemento de la lista pueda intercambiarse con cualquier otro elemento de la lista. Mi método SwapItem es solo un marcador de posición, en realidad todavía no tengo un método SwapItem.

Quiero que los argumentos que pase al método estén relacionados con los elementos que quiero intercambiar. Entonces, el primer elemento sería el elemento que he seleccionado con el mouse, y el otro elemento debería ser el elemento con el que se cruza el primer elemento.

preguntado el 01 de julio de 12 a las 16:07

Vaya y aprenda el lenguaje C#, y luego regrese y obtendrá ayuda. Es claro para mí que no entiendes los conceptos básicos de la programación, el ciclo for debería estar entre las primeras cosas que aprendas. Recomendaría que comenzara aprendiendo C++ primero, para que pueda comprender los conceptos básicos de la programación y programar de manera eficiente en lenguajes de nivel superior como C#, pero esto depende de usted. -

En primer lugar, sé que he estado bastante molesto preguntando tanto. Pero por eso vine aquí, para aprender. Y sé lo que es un bucle for, simplemente no veo por qué lo necesito aquí. La única vez que mis valores a y b son algo además de -1 es cuando tengo un elemento seleccionado y hago clic en otro elemento. De esa manera pasará el control de si e intercambiará los elementos. No veo lo que he hecho mal aquí para ser honesto. Lo único que tengo problemas es obtener el valor b, porque tengo que verificar si hay colisión entre dos elementos en la misma lista. -

Mire nuevamente mi respuesta, edité, espero que lo entienda. -

Debería tener suficiente información ahora para resolverlo, ya sea con mi propio método o con el tuyo. Muchas gracias por tu ayuda. -

Su método funciona bien, pero se retrasa mucho, a diferencia de foreach. Así que tendré que usar foreach. Pero debería funcionar. -

2 Respuestas

Para intercambiar un elemento de la lista, puede escribir un método de extensión ellos.

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

Recuerde poner el método de extensión dentro de una clase estática.

entonces puedes hacer:

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

respondido 31 mar '14, 15:03

¡+1 por usar el método de extensión! - Adrian K.

¿Cómo puedes declarar .Swap así cuando tienes que declarar ExtensionMethods.Swap... - Obsivus

@Obsivus, no estoy muy seguro de tu pregunta, ¿estás tratando de preguntar cómo El método de extensión funciona ? - Habib

Nvm estaba pensando mal, lo siento. Subirá la respuesta :) Funcionó perfectamente - Obsivus

@Obsivus, no tengo idea de cómo lo estás usando. Declararlo dentro de una clase estática pública, y luego debería estar disponible con List<T> - Habib

Para intercambiar los valores de dos variables, el método más fácil es usar referencias. Este es un ejercicio de puntero clásico en C++, pero también se puede aplicar a 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;
}

El algoritmo utilizado es muy sencillo, y la explicación suele hacerse así: tienes dos vasos, uno con agua y otro con aceite. Para poner el aceite en el primer vaso, necesitarás usar un tercer vaso, poner el agua dentro, luego poner el aceite en el primer vaso y el agua en el segundo.


Esto es lo que tenía en mente. Busque los comentarios, para que pueda entender lo que está pasando.:

// 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])
    }
}

Respondido 02 Jul 12, 15:07

Hmm... ¿qué estás tratando de intercambiar exactamente? El inventario parece ser el contenedor, y los otros parámetros en el código de ejemplo son artículo y artículo, que es lo mismo... - Tibi

Lo que no entiendo es que está tratando de reemplazar 'elemento' con 'elemento', ¿está tratando de intercambiar un objeto consigo mismo? Para corregir el error, puede reemplazar foreach con for e iterar con un valor de índice en su lugar. También deberá reemplazar el artículo con inventario [índice]... - Tibi

No, 'elemento' mantendrá su valor durante todo el bloque de código y luego lo cambiará al siguiente valor en la lista, lo mantendrá nuevamente durante todo el bloque de código y así sucesivamente. Creo que desea intercambiar dos elementos con índices diferentes de la lista, por lo que debe realizar el reemplazo del que le hablé. - Tibi

Sí, pero no quiero que esos índices estén 'codificados'. Índice a = el elemento que estoy seleccionando. Índice b = el elemento con el que colisiona el elemento a. - user1476943

Exactamente, ¿por qué no hacer dos variables a y b que tengan estos valores e intercambiar el inventario [a] con el inventario [b]? También debe reemplazar foreach con for, porque no puede modificar los valores en una lista mientras realiza un bucle con foreach. - Tibi

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.