Kontenery w języku D

Ostatnio pisząc jakiś programik w D poczułem potrzebę użycia listy, chwilę pomyślałem no i doszedłem do wniosku, że takie coś musi być w bibliotece, przecież nie będę tego pisał sam, jak to miało miejsce w c ;). Przeszukuję tego Phobosa i niestety na nic nie natrafiłem (nie wykluczam, że nie istnieje), tak więc pozostaje użycie czegoś takiego:

Typ tab[];
Typ a = new Typ();
tab ~= a;

Owszem jest to ciekawy krok w przód w porównaniu do c, ładnie tablica sama zwiększa rozmiar, ale to nie to czego szukałem. Jako osoba ostatnimi czasy pisząca w Javie miałem „potrzebę” używania wspaniałych ArrayList i HashMap, dalsze poszukiwania doprowadziły mnie do Tango i takiego odkrycia:

import tango.io.Stdout;
import tango.util.container.LinkedList;
import tango.util.container.HashMap;

void main() {
	LinkedList!(int) q = new LinkedList!(int);
	q.append(2); q.prepend(1); q.append(3);
	foreach(i; q) {
		Stdout(i).newline();
	}
	q.add(4);
	Stdout(q.get(0)).newline();
	q.size(); //ilosc elementow w liscie
	q.head(); //zwraca pierwszy element listy, nie usuwa go
	q.removeHead(); //zwraca pierwszy element listy i usuwa go
	q.tail(); //ostatni element listy
	q.removeTail();
	q.remove(1); //usuwa z listy element o podanej wartosci
	q.removeAt(0); //usuwa z listy element z danej pozycji
	q.clear(); //usuwa wszystkie elementy z listy
	
	HashMap!(int, int) m = new HashMap!(int, int);
	m.add(1, 12); m.add(2, 43); m.add(3, 34);
	foreach(i; m) {
		Stdout(i).newline();
	}
	int x; m.get(1, x);
	Stdout(x).newline();
	Stdout(m.opIndex(1)).flush();
	m.size(); //ilosc elementow w odwzorowaniu
	m.containsKey(1); //sprawdza czy dany klucz istnieje, zwraca true lub false
	m.contains(12); //sprawdza czy taka wartosc istnieje, zwraca true lub false
	m.removeKey(1); //usuwa z odwzorowania element o danym kluczu
	m.remove(43); //usuwa z odwzorowania element o danej wartosci
	m.clear(); //usuwa wszystkie elementy z odwzorowania
}

prawda, że wygląda lepiej :D

Przejdźmy teraz do krótkiego omówienia kodu. 6 linia to deklaracja listy, która będzie przechowywała zmienne typu int, ogólnie trochę dziwnie to wygląda, do tej pory spotkałem się z zapisem <typ> a tutaj !(typ), no ale nic idziemy dalej. 7 linia to dodanie elementów do listy, append dodaje element na koniec listy, prepend na początek, kolejna linia to wspaniał‚a pętla foreach, która „przechodzi” przez wszystkie elementy listy udostępniając je jako zmienną (w moim przypadku i). Linia 11 wygląda ładnie, jednak dla mnie nie była zbyt intuicyjna, przyzwyczajony, że add dodaje element na końcu listy tutaj się trochę zdziwił‚em, gdyż jest to alias do prepend a nie append (co sprawdzamy w kolejnej linii). Linii 13-20 nie będę opisywał, jest to kilka funkcji jakie oferuje klasa LinkedList i opisane są w kodzie.

Przejdźmy teraz do HashMap, najprościej mówiąc jest to odwzorowanie przekształcające jedną wartość na drugą, np. jako klucz możemy mieć czyjś nick, a jako wartość jego numer telefonu ;), oczywiście klucze muszą być unikatowe. Jednak dla uproszczenia zastosowałem int i int, gdyż nie ważny jest przykład a idea :D. Najpierw tworzymy zmienną HashMap, podajemy jej dwa typy, pierwszy to typ klucza, a drugi to typ wartości. W linii 23 dodajemy elementy do mapy (klucz, wartość), następnie prezentacja wspomnianej już pętli foreach. 27 linia może być dość ciekawa, funkcja get ponownie dość mało intuicyjna, gdyż nie zwraca nam wartości przyjmując jako parametr klucz, tylko przyjmuje dwie wartości, pierwsza klucz, a druga to zmienna pod jaką ma zostać zapisana wartość, zwraca true (jeżeli podany klucz istnieje) lub false (jeżeli nie istnieje). Rozwiązanie może i ciekawe, ale jeżeli ktoś woli stare „podejście” to może użyć funkcji opIndex (linia 29), która zwraca wartość po podaniu klucza. Dalsze funkcje klasy HashMap opisane są w kodzie.

Oczywiście wypisałem tutaj tylko 2 częściej używane moim zdaniem kontenery i to nie z wszystkimi oferowanymi przez nie funkcjami, po dalszą wiedzę odsyłam do dokumentacji biblioteki Tango.

9 lipca 2009 | język D

Zostaw odpowiedź