Dar vieno analitiko svetainė

Petras Kudaras

Švartzinės transformacijos

Šiandien skaičiausi apie Švartzines transformacijas. Tai tokia technologija, kuri labai praverčia sortinant
sudėtingus dalykus. Tarkime turim krūvą įrašų, kuriuose įrašyti vardas
ir pavardė (Na, stilium „Petras Kudaras“) ir norim
susortinti šiuos įrašus pagal pavardę abėcėlės tvarka. Paprasčiausia
būtų daryti taip:

@susortintas = sort {
               ($vardas1, $pavarde1) = split / /, $a;
               ($vardas2, $pavarde2) = split / /, $b;
               $pavarde1 cmp $pavarde2
} @nesortintas;

Tik čia slypi nemaža problema: kiekvieno lyginimo metu iš naujo
išsitraukinėjam pavardes, tad jei sąrašas, kurį reikia susortinti
labai ilgas, gali tekti ilgai laukti rezultatų. Čia padeda Švartzinė
transformacija, kurios esmė ta, kad pavardes galime išsitraukti vieną
kartą, tai išsisaugoti, ir lyginimui naudoti jau išsaugotas reikšmes.
Štai kodas:

@susortintas = map { $_->[0] }
               sort { $a->[1] cmp $b->[1] }
               map { [$_, (split)[1] ] }
               @nesusortintas;

Norint susigaudyti kas čia vyksta, reikia kodą skaityti nuo galo.
Pirmiausia, nesusortintas masyvas perleidžiamas per funkciją
map {}, kuri kiekvienam elementui sukuria
nuorodą į anoniminį masyvą, kurio pirmas elementa syra toks pats kaip
nesusortinto masyvo elementas, o antras – jau išskirta pavardė.
Čia dar aišku labai gudriai panaudojama split
funkcija, nes jei jai neperduodame jokių argumentų, tai ji splitina
$_ pagal tarpus (tiksliau pagal
whitespace). Po to šita sukurta nuoroda į anoniminį masyvą
perduodama funcijai sort, kuri ir atlieka visą
darbą, sortindama antrąjį elementą (kuriame yra pavardė). Paskutinis
map atkuria tvarką iš anoniminės nuorodos
padarydamas normalų elementą. Paprasta, ar ne? :)

Beje, galvojau gal padarysiu ką nors panašaus ant PHP, bet labai
jau ten sudėtingai tie array_map ir
usort naudojami. Ech…