2013-03-26 16 views
13

Więc jestem przyzwyczajony do posiadania zagnieżdżonej tablicy lub mapy ustawień w moich aplikacjach. Próbowałem ustawienie jednego w Clojure tak:Clojure dostaje zagnieżdżoną wartość mapy

(def gridSettings 
    {:width 50 
    :height 50 
    :ground {:variations 25} 
    :water {:variations 25} 
    }) 

I zastanawiałem się, czy znasz dobry sposób wciągania wartość zagnieżdżona? Próbowałem pisać: Które działa, ale jest to backwords i raczej nieporęczne, szczególnie jeśli dodaję kilka poziomów.

+1

Zarówno mtaka i odpowiedzi dbyrne są wspólne sposoby rozwiązania tego problemu. Użyj tego, co uderzy w twoją fantazję! Zauważyłem, że wejście zwiększa czytelność intencji. – WolfeFan

+0

Wow wszystkie dobre odpowiedzi :) Dzięki –

+1

Myślę, że nadszedł czas, aby zaakceptować jedną z tych odpowiedzi. Moje serce mówi * dbyrne *, ale moja głowa mówi * mtyaka * :) – joelittlejohn

Odpowiedz

25

To co robi get-in:

(get-in gridSettings [:ground :variations]) 

Z docstring:

clojure.core/get-in 
([m ks] [m ks not-found]) 
    Returns the value in a nested associative structure, 
    where ks is a sequence of keys. Returns nil if the key 
    is not present, or the not-found value if supplied. 
20

można użyć thread-first macro:

(-> gridSettings :ground :variations) 

wolę -> przez get-in z wyjątkiem dwóch specjalnych przypadków:

  • Gdy klucze są dowolną sekwencją ustaloną w czasie wykonywania.
  • Przy podawaniu nieodnalezionej wartości jest przydatna.
+0

jaki będzie wynik, jeśli '(: ground gridSettings)' będzie zerowe? – arajek

+2

Wynik całego wyrażenia będzie po prostu "zero". Nie zostanie zgłoszony wyjątek. – dbyrne

+0

'(: zero zerowe); => zero'. Używanie '->' chyba że celowo potrzebujesz czegoś innego również wydaje się być idiomatycznym Clojure. – danneu

9

Niezależnie od tego, co innych odpowiedzi wspomniał (get-in i -> makro), czasami chcesz pobrać wiele wartości z mapy (zagnieżdżony lub nie), w tych przypadkach, de-strukturyzacji może być bardzo pomocna

(let [{{gv :variations} :ground 
     {wv :variations} :water} gridSettings] 
    [gv wv]) 
0

Mapy są funkcjami częściowymi (jak w sumie nie). Tak więc można po prostu zastosować je jako funkcje. Na podstawie mapy z pytania:

(gridSettings :ground) 
;=> {:variations 25} 

Wynikiem jest mapa. Tak, to może być ponownie zastosowany, co skutkuje bardzo podobne (ale nie do tyłu) „składni”, jak proponuje się w pytaniu:

((gridSettings :ground) :variations) 
;=>25 
Powiązane problemy