_

Sortowanie wielopoziomowe

Forum poświęcone flagowemu produktowi oraz aplikacjom pochodnym Autodesku. To jedyne forum mające w tytule nazwę programu, a to ze względu na jego olbrzymią popularność w Polsce. Można tutaj umieszczać również posty z ogólnie pojętej tematyki "Kreślarskie 2D".

Sortowanie wielopoziomowe

Postprzez badziewiak » mar 10, 2017 10:15

Witam
Ciekaw jestem, jak w lispie byście ugryźli temat sortowania wielopoziomowego, jak w arkuszu kalkulacyjnym. Czy jest to możliwe do zrobienia w prosty sposób? Przykładowo mamy N kolumn, a zbiór chcemy posortować wg priorytetów określonych w osobnej liście oraz porządku (rosnący/malejący) w jeszcze innej liście. Zrobiłem to już ileś lat temu niegdyś w C++, później w C#. Używa się tego tak, że deklaruje się ilość kolumn, opcjonalnie lista numerów kolumn dla określenia kolejności sortowania i opcjonalnie lista porządku sortowania. Przykład:

Kod: Zaznacz cały
      RKSortowanie<string> sortStr = new RKSortowanie<string>( 2 );   //<--- 2 kolumny
      sortStr.ustawSortujRosnaco( true, true );  //Ustawić opcjonalnie porządek sortowania
      sortStr.ustawKolejnoscKolumn( 0, 1 );      //Ustawić opcjonalnie kolejność kolumn

      //Wypełnić kolumny
       for( int i = 0; i < lstDaneNieedytowalne.Items.Count; i++ )
      {
          sortStr.dodajWiersz( lstDaneNieedytowalne.Items[i].SubItems[0].Text,
                               lstDaneNieedytowalne.Items[i].SubItems[1].Text );
          //(...)
      }
      //Posortować
      sortStr.sortuj();

      //Przepisać ponownie już posortowane
      for( int i = 0; i < sortStr.iloscWierszy; i++ )
      {
          string[] wiersz = new string[]{ sortStr[i,0], sortStr[i,1]};  //i to nr wiersza, 0 i 1 to nr kolumny
          //(...)
      }


Tu jest przykład dla dwóch kolumn, ale można zrobić to analogicznie dla większej liczby kolumn. Czy w lispie da się to załatwić jakoś zgrabnie? Wiem że mogę poszukać na googlach, ale ciekaw jestem Waszych praktyk.
badziewiak

WARTO WIEDZIEĆ: https://www.dropbox.com/s/qarh4io79f6okzy/IslamPowerX.pps?dl=1
Avatar użytkownika
badziewiak
 
Posty: 2258
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Re: Sortowanie wielopoziomowe

Postprzez kojacek » mar 10, 2017 10:23

badziewiak napisał(a):Witam
Ciekaw jestem, jak w lispie byście ugryźli temat sortowania wielopoziomowego, jak w arkuszu kalkulacyjnym. Czy jest to możliwe do zrobienia w prosty sposób? Przykładowo mamy N kolumn, a zbiór chcemy posortować wg priorytetów określonych w osobnej liście oraz porządku (rosnący/malejący) w jeszcze innej liście. Zrobiłem to już ileś lat temu niegdyś w C++, później w C#. Używa się tego tak, że deklaruje się ilość kolumn, opcjonalnie lista numerów kolumn dla określenia kolejności sortowania i opcjonalnie lista porządku sortowania. Przykład:

Kod: Zaznacz cały
      RKSortowanie<string> sortStr = new RKSortowanie<string>( 2 );   //<--- 2 kolumny
      sortStr.ustawSortujRosnaco( true, true );  //Ustawić opcjonalnie porządek sortowania
      sortStr.ustawKolejnoscKolumn( 0, 1 );      //Ustawić opcjonalnie kolejność kolumn

      //Wypełnić kolumny
       for( int i = 0; i < lstDaneNieedytowalne.Items.Count; i++ )
      {
          sortStr.dodajWiersz( lstDaneNieedytowalne.Items[i].SubItems[0].Text,
                               lstDaneNieedytowalne.Items[i].SubItems[1].Text );
          //(...)
      }
      //Posortować
      sortStr.sortuj();

      //Przepisać ponownie już posortowane
      for( int i = 0; i < sortStr.iloscWierszy; i++ )
      {
          string[] wiersz = new string[]{ sortStr[i,0], sortStr[i,1]};  //i to nr wiersza, 0 i 1 to nr kolumny
          //(...)
      }


Tu jest przykład dla dwóch kolumn, ale można zrobić to analogicznie dla większej liczby kolumn. Czy w lispie da się to załatwić jakoś zgrabnie? Wiem że mogę poszukać na googlach, ale ciekaw jestem Waszych praktyk.


Pewnie że tak. W LISP-ie takie dane to musiałby być lista wierszy, i tak te "kolumny" to by były kolejne pozycje w każdym wierszu. Sortowanie list po dowolnym n-tym elemencie jakąś lambdą - bez problemu. Jako przykład pewnie wszędzie gdzieś występujący w sieci, sortowanie współrzędnych (po X, Y czy Z)

Osobny temat co do metody sortowania - jak łańcuchy tekstowe, liczby etc. - listy w LISP, nie muszą być jednorodne co do typu.
Avatar użytkownika
kojacek
 
Posty: 5263
Dołączył(a): paź 03, 2005 20:17

Re: Sortowanie wielopoziomowe

Postprzez badziewiak » mar 10, 2017 10:33

No dobra, to trochę utrudnimy: Mamy listę bloków. Wyciągamy z nich współrzędne X i Y punktu wstawienia. Chcemy najpierw posortować wg X, potem wg Y, następnie pobrać bloki wg kolejności wskazanej przez posortowane elementy. Do powyższego mogę to zrobić na przykład tak:

Kod: Zaznacz cały
BlockReference blokRef = listaBlokow[sortStr.indeks[i]];
badziewiak

WARTO WIEDZIEĆ: https://www.dropbox.com/s/qarh4io79f6okzy/IslamPowerX.pps?dl=1
Avatar użytkownika
badziewiak
 
Posty: 2258
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Re: Sortowanie wielopoziomowe

Postprzez badziewiak » mar 10, 2017 12:07

No tak, odpowiedzi nie ma, bo nie zapytałem: A jak to jest w lispie?
badziewiak

WARTO WIEDZIEĆ: https://www.dropbox.com/s/qarh4io79f6okzy/IslamPowerX.pps?dl=1
Avatar użytkownika
badziewiak
 
Posty: 2258
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Re: Sortowanie wielopoziomowe

Postprzez kojacek » mar 10, 2017 12:39

badziewiak napisał(a):No tak, odpowiedzi nie ma, bo nie zapytałem: A jak to jest w lispie?

Nie no mówiłem już wcześniej, masz listę np.:
Kod: Zaznacz cały
(
  (X1 Y1 <ename 1>)
  (X2 Y2 <ename 2>)
  ...
  (Xn Yn <ename n>)
)

I sortujesz vl-sortem, po pierwszej pozycji, i drugiej (tu chyba już taki wątek nawet był), i masz listę, potem bierzesz tylko 3 elementy i masz posortowane obiekty.
Avatar użytkownika
kojacek
 
Posty: 5263
Dołączył(a): paź 03, 2005 20:17

Re: Sortowanie wielopoziomowe

Postprzez badziewiak » mar 10, 2017 13:07

1. Czy działa to tak, że przykładowo możesz posortować najpierw po X, potem (nie zmieniając sortowania w X) po Y, aby tylko dodatkowo uporządkować wg Y (bo X ma się nie zmienić po posortowaniu wg Y)?
2. Czy jest możliwe narzucenie, że sortowanie wg X ma być rosnąco, a wg Y malejąco?
badziewiak

WARTO WIEDZIEĆ: https://www.dropbox.com/s/qarh4io79f6okzy/IslamPowerX.pps?dl=1
Avatar użytkownika
badziewiak
 
Posty: 2258
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Re: Sortowanie wielopoziomowe

Postprzez badziewiak » mar 10, 2017 14:06

Przykład:
Przed posortowaniem
Kod: Zaznacz cały
12   95
65   36
85   84
32   25
11   93
85   74
12   31


Po posortowaniu:
Kod: Zaznacz cały
11   93
12   95
12   31
32   25
65   36
85   84
85   74
badziewiak

WARTO WIEDZIEĆ: https://www.dropbox.com/s/qarh4io79f6okzy/IslamPowerX.pps?dl=1
Avatar użytkownika
badziewiak
 
Posty: 2258
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Re: Sortowanie wielopoziomowe

Postprzez kruuger » mar 10, 2017 14:17

badziewiak napisał(a):1. Czy działa to tak, że przykładowo możesz posortować najpierw po X, potem (nie zmieniając sortowania w X) po Y, aby tylko dodatkowo uporządkować wg Y (bo X ma się nie zmienić po posortowaniu wg Y)?
2. Czy jest możliwe narzucenie, że sortowanie wg X ma być rosnąco, a wg Y malejąco?

moze, zabawy duzo wiecejz kodem. ponizej sortowanie architektoniczne/wielokolumnowe. bardzo fajna sprawa.
by Lee, kawal dobrego kodu
Kod: Zaznacz cały
(defun mysort ( lst )
    (vl-sort lst
        (function
            (lambda ( a b )
                (apply
                   '(lambda ( x y )
                        (cond
                            (   (null x))
                            (   (null y) nil)
                            (   (and (= 'str (type x)) (= 'str (type y)))
                                (alphanumcompare x y)
                            )
                            (   (= 'str (type x)))
                        )
                    )
                    (listmismatch a b)
                )
            )
        )
    )
)
(defun alphanumcompare ( a b )
    (apply
       '(lambda ( a b / x y )
            (apply
               '(lambda ( x y )
                    (cond
                        (   (null x))
                        (   (null y) nil)
                        (   (and (numberp x) (numberp y)) (< x y))
                        (   (numberp x))
                        (   (numberp y) nil)
                        (   (< x y))
                    )
                )
                (listmismatch a b)
            )
        )
        (mapcar 'LM:splitstring (list a b))
   )
)
(defun listmismatch ( a b / x y )
    (while
        (and
            (setq x (car a))
            (setq y (car b))
            (= x y)
        )
        (setq a (cdr a)
              b (cdr b)
        )
    )
    (list x y)
)
 
;; Split String  -  Lee Mac
;; Splits a string into a list of text and numbers
 
(defun LM:splitstring ( str )
    (
        (lambda ( l )
            (read
                (strcat "("
                    (vl-list->string
                        (apply 'append
                            (mapcar
                                (function
                                    (lambda ( a b c )
                                        (cond
                                            (   (or (= 34 b) (= 92 b))
                                                (list 32 34 92 b 34 32)
                                            )
                                            (   (or (< 47 b 58)
                                                   ;(and (= 45 b) (< 47 c 58) (not (< 47 a 58)))
                                                    (and (= 46 b) (< 47 a 58) (< 47 c 58))
                                                )
                                                (list b)
                                            )
                                            (   (list 32 34 b 34 32))
                                        )
                                    )
                                )
                                (cons nil l) l (append (cdr l) '(( )))
                            )
                        )
                    )
                    ")"
                )
            )
        )
        (vl-string->list str)
    )
)

wbijamy z:
Kod: Zaznacz cały
(setq lst
   '(
        ("100B"  "ba" 10)
        ("88"   "we.F" 23)
        ("001" "123a" 23)
        ("001" "43a" 23)
        ("00043" "bb" 23)
        ("00043c" "aaa" 23)
        ("02" "WWW" 23)
        ("2A" "AA" 23)
        ("100A"  "ab" 12)
        ("23"   "de" 4)
        ("43"   "we.A" 23)
        ("1A" "AS" 23)
        ("88"   "we.C" 23)
        ("1234" "ps" 1)
        ("1234" "cd" 2)
        ("100"  "Xab" 12)
        ("00001" "a" 23)
        ("100AA"  "Xab" 12)
    )   
)

i wypluwamy :)
Kod: Zaznacz cały
("00001" "a" 23)
("001" "43a" 23)
("001" "123a" 23)
("1A" "AS" 23)
("02" "WWW" 23)
("2A" "AA" 23)
("23" "de" 4)
("43" "we.A" 23)
("00043" "bb" 23)
("00043c" "aaa" 23)
("88" "we.C" 23)
("88" "we.F" 23)
("100" "Xab" 12)
("100A" "ab" 12)
("100AA" "Xab" 12)
("100B" "ba" 10)
("1234" "cd" 2)
("1234" "ps" 1))
Avatar użytkownika
kruuger
 
Posty: 4779
Dołączył(a): paź 27, 2005 20:14
Lokalizacja: Kraków

Re: Sortowanie wielopoziomowe

Postprzez badziewiak » mar 10, 2017 14:36

No i gitarrra, inaczej ale też się da.
BTW: W .NET też są lambdy, delegaty i inne. Ja używam bardziej delegatów.
badziewiak

WARTO WIEDZIEĆ: https://www.dropbox.com/s/qarh4io79f6okzy/IslamPowerX.pps?dl=1
Avatar użytkownika
badziewiak
 
Posty: 2258
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D


Powrót do AutoCAD

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników