Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Ordenar TStringList con objetos (https://www.clubdelphi.com/foros/showthread.php?t=95102)

Angel.Matilla 04-03-2021 18:57:20

Ordenar TStringList con objetos
 
Tengo un TStringList que cargo a partir de elementos seleccionados en un TListView así:
Código:

for (nItem = 0; nItem < ListView1->Items->Count; nItem ++)
{
    if (!ListView1->Items->Item[nItem]->Checked)
          continue;

    cAux = "";
    if (InputQuery(Application->Title, UpperCase(ComboBox1->Items->Strings[ComboBox1->ItemIndex]) + "\n" + ListView1->Items->Item[nItem]->Caption + "\nIndique la cantidad", cAux) && StrToIntDef(cAux, 0) > 0)
          slDatos->AddObject(ListView1->Items->Item[nItem]->Caption, (TObject *)StrToInt(cAux));
}

Supongamos que una vez cargado el TStringList quedara así:
Cita:

Dato 1 - 100
Dato 2 - 200
Dato 3 - 300
Dato 4 - 400
Dato 5 - 500
y necesito ordenar la lista descendentemente para que queda así:
Cita:

Dato 5 - 500
Dato 4 - 400
Dato 3 - 300
Dato 2 - 200
Dato 1 - 100
Para ordenarla estoy usando esto:
Código:

for (int nUno = 1; nUno < slDatos->Count; ++ nUno)
    for (int nDos = 0; nDos < slDatos->Count - nUno; nDos ++)
          if ((int)(TObject*)slDatos->Objects[nDos] < (int)(TObject*)slDatos->Objects[nDos + 1])
          {
              Objeto = new TObject();
              Objeto = slDatos->Objects[nDos];
              slDatos->Objects[nDos]    = slDatos->Objects[nDos + 1];
              slDatos->Objects[nDos + 1] = Objeto;
          }

Evidentemente Objeto está declarado como TObject *Objeto. Pero cuando termina me ha ordenado bien las cantidades pero no los literales y queda así:
Cita:

Dato 1 - 500
Dato 2 - 400
Dato 3 - 300
Dato 3 - 200
Dato 5 - 100
¿Qué estoy haciendo mal?

ecfisa 04-03-2021 23:55:27

Hola.

Creo que te resultará mas sencillo usar el método CustomSort de la clase TStringList, ejemplo:

Código PHP:

int __fastcall SortCompareTStringListTSint i1int i2 )
{
   return 
TS->Strings[i2].AnsiCompare(TS->Strings[i1]);
}


void __fastcall TForm1::Button1Click(TObject *Sender)
{
  
TStringList *TS = new TStringList;

  
TS->Clear();
  
TS->AddObject("dato1",(TObject*)100);
  
TS->AddObject("dato2",(TObject*)200);
  
TS->AddObject("dato3",(TObject*)300);
  
TS->AddObject("dato4",(TObject*)400);
  
TS->AddObject("dato5",(TObject*)500);

  
// ordenar
  
TS->CustomSort(SortCompare);

  
// mostrar
  
for(int i 0TS->Counti++)
    
Memo1->Lines->Add(TS->Strings[i] + " - " +
       (int)(
TS->Objects[i]));

  
delete TS;


Salida:


Saludos :)

Angel.Matilla 05-03-2021 10:32:38

No conocía el método. Muchas gracias. No obstante no lo veo claro: Haces una llamada a una función SortCompare pero ¿no pasas parámetros en la misma? ¿No falta nada en esa llamada? Además, tal como has puesto el código, yo entiendo que se comparan únicamente dos elementos (i1 e i2).

ecfisa 05-03-2021 15:52:31

Hola.

El método CustomSort ordena el TStringList mediante una función de comparación personalizada cuyo puntero recibe como argumento.
Esta, deberá comparar dos elementos de la lista y devolver un número que será:
  • Negativo si el primer elemento es menor que el segundo.
  • Cero si ambos elementos sin iguales.
  • Positivo si el primer elemento es mayor que el segundo.
En el ejemplo, el método CustomSort asume this como el parámetro TS, mientras que 0 y TS->Count como los sucesivos índices de la lista.

Para ordenar de forma ascendente dispones del método Sort de forma directa, pero también puedes usar CustomSort del siguiente modo:
Código PHP:

int __fastcall SortCompareTStringListTSint i1int i2 )
{
   return 
TS->Strings[i1].AnsiCompare(TS->Strings[i2]); 

Prueba el ejemplo para verificar.


Saludos :)

Angel.Matilla 06-03-2021 09:47:48

Perfecto. Cuando lo probé ayer, antes de escribir el mensaje, me estaba dando un error de compilación y era porque había declarado mal esa función SortCompare. Muchísimas gracias.


La franja horaria es GMT +2. Ahora son las 07:51:35.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi