2014-05-24 18 views
6

mamJak "oznaczyć" węzeł w strukturze danych Clojure?

  • strukturę danych Clojure, nazwijmy to dom, drzewa wektorów i mapy nieokreślony głębokości;
  • konkretny węzeł, nazwijmy go węzłem focus, określanym jako ścieżką do drzewa: sekwencją kluczy, które można przedstawić get-in.

będę decydując się na skoncentrowanych węzła w jednej funkcji i chcę jakoś reprezentować że wybór skoncentrowanych węzła w sposób, który może zostać przekazany do innej funkcji w sposób, który nie narusza niezmienność i nie jest w konflikt z trwałymi strukturami danych Clojure.

Kiedy przemierzać drzewo, chcę traktować węzeł focus inaczej: na przykład, gdybym był druk drzewo, może chcę wydrukować węzeł focus w pogrubioną.

Gdybym używał języka C lub Java, mógłbym zapisać wskaźnik/odwołanie do węzła focus, który mógłbym porównać z bieżącym węzłem podczas przechodzenia przez drzewo. Nie sądzę, że jest to właściwy sposób na zrobienie tego w Clojure: czuje się odrażająco i jestem pewien, że jest jakiś sposób, aby to zrobić, wykorzystując trwałe struktury danych Clojure.

Rozwiązanie musi działać w Clojure i ClojureScript.

Opcje mogę myśleć to:

  1. Store odniesienie i sprawdzić przeciwny.
  2. Dołącz znacznik do danego węzła.
  3. Jednocześnie rekurencyjnie do drzewa i wzdłuż ścieżki do zaznaczonego węzła.

    • Opcja (1) jest nieatrakcyjna, jak już wyjaśniłem.
    • Opcja (2) wydaje się najlepsza i bezbolesna, biorąc pod uwagę trwałe struktury danych.
    • Opcja (3) jest podobna do opcji (2), z tym wyjątkiem, że łączy etapy oznaczania i przechodzenia .

Jestem pewien, że jest to wspólny problem. Czy istnieje standardowe rozwiązanie tego problemu?

+0

Myślę, że możesz użyć metadanych do implementacji 2, ale nie znam ogólnego rozwiązania. –

+0

Dziękuję. Mógłbym używać metadanych, ale prawdopodobnie nie. Pytanie jest nieco szersze niż wdrożenie. – Joe

+0

Nigdy nie boli, aby to ponownie przeczytać, ale nie sądzę, że zadaję pytanie oparte głównie na opiniach. Jest całkowicie możliwe (i nie mam możliwości poznania), że istnieje standardowy wzorzec idiomatyczny do robienia tego. Jeśli odpowiedź brzmi "nie", jest to poprawna odpowiedź. – Joe

Odpowiedz

2

Proponuję ponowne rozważenie sugestii @ MerceloMorales: używać metadanych. Obiekt twojego węzła ma mieć przypadkowy atrybut, który nie wpływa na jego normalne funkcje. Właśnie do tego przeznaczone są metadane. I działa w ClojureScript. Jedynym powodem, dla którego mogę myśleć o metodzie , a nie, jest to, że wartość węzła nie jest obiektem Clojure, ale jest na przykład liczbą.

W dokumencie The Clojure Cookbook, 2.22. Keeping Multiple Values for a Key Luke Vanderhart używa metadanych do rozwiązania podobnego problemu: oznaczania wpisów, które należy interpretować jako kolekcje, a nie pojedyncze wartości.

Innym rozwiązaniem może być użycie suwaka do przechodzenia/modyfikacji drzewa węzłów.Zamki są zaimplementowane w kategoriach - zgadłeś - metadanych.

Podzielam twoje obawy dotyczące metadanych: wydaje mi się, że trudno jest dołączyć do danych jakieś stare rzeczy - na przykład infekować je pasożytem. Jednak jest tak samo niezmienna jak część obiektu jak każda inna.


Sugestia używać zamków jest naiwny: The standard clojure zippers są przeznaczone do hierarchii kolejnych pojemników, a nie te, które asocjacyjnych.

+0

Dzięki za odpowiedź. Być może nie miałem jasności co do tego, co powiedziałem o metadanych: nie mam problemu z jego używaniem, ale nie ma znaczenia, czy używam metadanych czy innej metody przechowywania "znaku". Właśnie zadawałem bardziej ogólne pytanie o to podejście. – Joe

+0

Myślę, że starałem się przekazać moje pytanie, a może nie powinienem dawać przykładu. Chcę tylko wskazać określony węzeł w drzewie na podstawie ścieżki, aby inna funkcja mogła zidentyfikować węzeł. Zobaczę, czy mogę edytować pytanie, aby było jaśniejsze. – Joe

+0

@Joe Bardzo dobrze wkładam :). Przykłady pomocy. – Thumbnail

1

Zobacz opis marki Brandon Bloom pod numerem Dendrology talk, aby uzyskać lepszy przegląd takich pytań.

Wierzę, że łatwość "oznaczania" lub w inny sposób aktualizowania danych opartych na drzewach leży u podstaw jego silnej rekomendacji, aby zawsze reprezentować węzły jako mapy zagnieżdżone, a nie wektory (lub mieszankę wektorów i map). Znak na podstawie ścieżki opisanym przez wektor kluczy jest wtedy tak proste, jak:

(update-in tree-data path assoc :is-focussed true) 

Oryginalna struktura danych jest niezmienna, a nowy zwrócony przez update-akcjami wszystko strukturalnie z oryginałem wyjątkiem zaktualizowanego węzła który jest teraz łatwo testowany pod kątem właściwości :is-focussed po przejściu.

Powiązane problemy