Разбор структуры вложенного массива - PullRequest
1 голос
/ 21 января 2012

Я пытаюсь проанализировать структуру вложенного массива следующей формы:

[element [[child1] [child2] [child3 [[subchild1] [subchild2]]]]]

Я также хотел бы вернуть список со всеми символами (и ничем иным), независимо от глубины вложенности;однако я не ищу flatmap или flatten и т. д., поскольку мне нужно выполнить более сложную дополнительную работу с каждым элементом.

Это то, что я до сих пор придумал:

(defn create-element [rs element]
  (if (symbol? element)
    (cons element rs)
    rs))

(defn parse
  ([rs element] (create-element rs element))
  ([rs element [children & more]] (if (nil? more)
                                    (parse (parse rs element) (first children))
                                    (parse (parse rs element) (first children) more))))

(defn n-parse [element]
  (apply parse () element))

Это прекрасно работает для следующего ввода:

=> (n-parse ['bla [['asd] ['kkk] ['sss]]])
(sss kkk asd bla)

Но это не работает:

=> (n-parse ['bla [['asd] ['kkk [['ooo]]] ['sss]]])
(sss kkk asd bla)

Я все еще пытаюсь обернуть голову вокругтипы, но, кажется, не удается сделать это правильно.Например, Haskell упрощает сопоставление с образцом и т. Д., В то время как Clojure не допускает перегрузки той же функции арности.

Также есть более краткий / идиоматический способ (без необходимости прибегать к нему, если?)Я предпочитаю чистые решения Clojure (без внешних библиотек), так как на самом деле это проект Clojurescipt.

Большое спасибо за любую помощь!

1 Ответ

0 голосов
/ 21 января 2012

Я не вижу, что не так с Flatten. Если вы хотите сначала поработать над элементами, сначала поработайте, а затем сгладьте результат:

(defn map-tree
      "Example: (map-tree + [1 2 [3 5]] [3 4 [5 6]])"
    [f & trees]
    (if (every? coll? trees)
        (apply map (partial map-tree f) trees)
        (apply f trees)))

(defmulti transformator identity)
;; transform 'sss element into something special
(defmethod transformator 'sss [_] "sss")
;; default transformation
(defmethod transformator :default [v] v)

Тест:

user> (flatten (map-tree transformator '[bla [[asd] [kkk] [sss]]]))
(bla asd kkk "sss")
user> 

Разве это не сработает?

...