Szukaj…
Uwagi
Słowniki w Tcl to wartości, które zawierają odwzorowanie z dowolnych wartości na inne dowolne wartości. Zostały one wprowadzone w Tcl 8.5, choć istnieją ograniczone wersje (obecnie nieobsługiwanego) Tcl 8.4. Słowniki są składniowo takie same jak listy z parzystą liczbą elementów; pierwsza para elementów to pierwszy klucz i wartość słownika, druga para to druga krotka.
A zatem:
fox "quick brown" dogs "lazy"
jest poprawnym słownikiem. Ten sam klucz może być wiele razy, ale jest dokładnie tak, jakby jego wartość była wcześniejsza; są to ten sam słownik:
abcd {1 2 3} defg {2 3 4} abcd {3 4 5}
abcd {3 4 5} defg {2 3 4}
Białe znaki są nieistotne, podobnie jak w przypadku list.
Ważną koncepcją ze słownikami jest kolejność iteracji; słowniki próbują użyć kolejności wstawiania kluczy jako kolejności iteracji, jednak po zaktualizowaniu wartości klucza, który już istnieje, nadpisuje się wartość tego klucza. Nowe klucze idą na końcu.
Odniesienia: dykt
Dołączanie listy do zagnieżdżonego słownika
Jeśli mamy ten słownik:
set alpha {alice {items {}} bob {items {}} claudia {items {}} derek {items {}}}
I chcesz dodać „widelec” i „orzechowe” do elementów Alicji, ten kod nie będzie działać:
dict lappend alpha alice items fork peanut
dict get $alpha alice
# => items {} items fork peanut
Ponieważ polecenie nie może wiedzieć, gdzie kończą się tokeny kluczy, a wartości, które mają być dołączane do listy, zaczynają się od tego polecenia, polecenie jest ograniczone do jednego tokena klucza.
Prawidłowy sposób dołączenia do wewnętrznego słownika jest następujący:
dict with alpha alice {
lappend items fork peanut
}
dict get $alpha alice
# => items {fork peanut}
Działa to, ponieważ dict with poleceniem pozwala nam przechodzić przez zagnieżdżone słowniki, tyle poziomów, ile podajemy tokenów kluczowych. Następnie tworzy zmienne o takich samych nazwach jak klucze na tym poziomie (tylko jedna tutaj: items ). Zmienne są inicjowane do wartości odpowiadającej pozycji w słowniku. Jeśli zmienimy wartość, ta zmieniona wartość zostanie użyta do zaktualizowania wartości elementu słownika po zakończeniu skryptu.
(Zauważ, że zmienne nadal istnieją po zakończeniu polecenia.)
Podstawowe użycie słownika
Tworzenie słownika:
set mydict [dict create a 1 b 2 c 3 d 4]
dict get $mydict b ; # returns 2
set key c
set myval [dict get $mydict $key]
puts $myval
# remove a value
dict unset mydict b
# set a new value
dict set mydict e 5
Klucze słownika można zagnieżdżać.
dict set mycars mustang color green
dict set mycars mustang horsepower 500
dict set mycars prius-c color orange
dict set mycars prius-c horsepower 99
set car [dict get $mycars mustang]
# $car is: color green horsepower 500
dict for {car cardetails} $mycars {
puts $car
dict for {key value} $cardetails {
puts " $key: $value"
}
}
Polecenie dict get może zgłosić błąd
set alpha {a 1 b 2 c 3}
dict get $alpha b
# => 2
dict get $alpha d
# (ERROR) key "d" not known in dictionary
Jeśli do pobrania wartości brakującego klucza użyto polecenia dict get pojawia się błąd. Aby uniknąć błędu, użyj dict exists :
if {[dict exists $alpha $key]} {
set result [dict get $alpha $key]
} else {
# code to deal with missing key
}
Jak radzić sobie z brakującego klucza oczywiście zależy od sytuacji: jeden prosty sposób to ustawić result do domyślnej wartości „pusta”.
Jeśli kod nigdy nie próbuje pobrać innych kluczy ze słownika, polecenie dict get oczywiście nie zawiedzie. Ale w przypadku dowolnych kluczy dict get to operacja, którą należy pilnować. Najlepiej, jeśli dict exists testowanie za pomocą dict exists , choć może również działać przechwytywanie wyjątków.
Iterowanie po słowniku
Możesz iterować zawartość słownika za pomocą dict for , który jest podobny do foreach :
set theDict {abcd {ab cd} bcde {ef gh} cdef {ij kl}}
dict for {theKey theValue} $theDict {
puts "$theKey -> $theValue"
}
Daje to wynik:
abcd -> ab cd bcde -> ef gh cdef -> ij kl
Otrzymasz te same dane wyjściowe, używając dict keys aby wyświetlić listę kluczy i iterować:
foreach theKey [dict keys $theDict] {
set theValue [dict get $theDict $theKey]
puts "$theKey -> $theValue"
}
Ale dict for jest bardziej wydajne.