[c#] sortowanie tablicy dwuwymiarowej

0

Cześć.

Piszę program i mam pewien problem. Mam mniej więcej taką listę danych w stringu:

dane[0,0] = "string";
dane[0,1] = "string";
dane[0,2] = "string";
dane[0,3] = "string";
dane[0,4] = "int";
dane[0,5] = "string";
dane[0,6] = "string";
dane[0,7] = "string";
dane[0,8] = "string";
dane[0,9] = "int";

Chcę sortować wg. 2 lub 4 itemu. Dodatkowo chciałbym się dowiedzieć jak sortować także wg 2 lub 4 ale od tyłu :)

0

jest Array.Sort, ale obsługuje tablice jednowymiarowe (albo zagnieżdżone) a nie prostokątne.
jest też List, w wielu wypadkach dużo wygodniejsze od tablic.
są też różne Dictionary i inne,
jest LINQ, które pozwala ci sortować i wybierać dane na wszystkie możliwe sposoby,

ale twoja tablica dwuwymiarowa akurat najmniej się do tego wszystkiego nadaje.

0

Odpowiem Ci dość połowicznie i w inny sposób niż może tego oczekujesz. Aktualnie nie mam dostepu do kompilatora, ale to co napisze powinno działać ;) Ostatnio się z tym męczyłem :)

Przede wszystkim ,widzę, że masz strukturę (s - string, s, s,s , i-int), czemu więc nie zrobić by jakieś klasy do tego ? Na szybko :

class MojaStruktura
{
public string a,b,c,d = null;
public int liczba = 0;

//konstruktor  sam sobie napisz :P
}

Mając klasę możemy stworzyć sobię listę :

List <MojaStruktura> Lista = new List<MojaStruktura>();

Dodajemy sortowanie wg liczb. Aby to zrobić skorzystamy z interface IComparable (z system.collection) który "daje" funkcję int CompareTo(object o);

rozbudowujemy naszą poprzednią klase :

class MojaStruktura:IComparable
{
public string a,b,c,d = null;
public int liczba = 0;

//-----dopisane -----
int IComparable.CompareTo(object o)
{
MojaStruktura tymczasowy = (MojaStruktura)o;
if(this.liczba > tymczasowy.liczba)
{
return 1;
// tak naprawde jeśli liczba z obiektu jest większa od liczby z obiektu do którego porównujemy, możemy zwrócić DOWOLNA liczbę dodatnia, nie ma znaczenia czy 1 czy 1000, tak samo z liczbą ujemną (-1), patrz niżej
}
else if(this.liczba < tymczasowy.liczba)
{
return -1;
}
else return 0;
}
//-----koniec dopisania-----

//konstruktor  sam sobie napisz :P
}

teraz już możemy zrobić taki manewr Lista.Sort();

dopisujemy sortowanie wg wartości drugiej czyli B

Aby określić wiele kryteriów sortowania musimy stworzyć sobię klasę dodatkową korzystającą z interface IComparer, który przyjmuje 2 obiekty.

class SortujWgNazwy : IComparer
{

int IComparer.Compare(object o1, object o2)
{
MojaStruktura ms1 = (MojaStruktura)o1;
MojaStruktura ms2 = (MojaStruktura)o2;
return String.Compare(ms1.b, ms2.b);
}
}

teraz aby posortować listę wg nazwy użyjemy :

Lista.Sort(SortujWgNazwy);
0

czemu więc nie zrobić by jakieś klasy do tego

akurat struct mogłoby być tu lepsze od class, a już na pewno nie należy w kontekście C# mieszać słów „klasa” i „struktura”.

// tak naprawde jeśli liczba z obiektu jest większa od liczby z obiektu do którego porównujemy, możemy zwrócić DOWOLNA liczbę dodatnia, nie ma znaczenia czy 1 czy 1000, tak samo z liczbą ujemną (-1), patrz niżej

dzięki temu niepotrzebne są żadne if-y, wystarczy odjąć jedną liczbę od drugiej.

Aby określić wiele kryteriów sortowania musimy stworzyć sobię klasę dodatkową korzystającą z interface IComparer, który przyjmuje 2 obiekty.

Począwszy od .Net bodajże 3.0 można użyć wyrażenia lambda:

            List<MojaStruktura> lista;
            ...
            lista.Sort((v, w) => v.b.CompareTo(w.b)); // sortowanie po b
            lista.Sort((v, w) => v.c.CompareTo(w.c)); // sortowanie po c

gdzie

	(v, w) => v.b.CompareTo(w.b)

oznacza funkcję (delegatę) przyjmującą dwa parametry v i w a zwracającą v.b.CompareTo(w.b).
Rezultat jest taki sam, jak w twoim przykładzie z jawną osobną funkcją, tylko kod jest krótszy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1