2011-09-14 29 views
6

私が理解しているように、ループを使用せずにClojureで再帰的に繰り返す構文は、短いシーケンスでは問題にならないかもしれません。ただし、反復関数を記述するためには、loop .. recur構文を使用することをお勧めします。ですから、私はまず最初に好きな方法から始めたいと思います。このデータを用いて試験した(その値を含まない配列構造)配列の骨格を返し変換するループ...再帰の再帰

しかし、私はこの機能を変換するために苦労してきた[編集]

(defn skl 
    [tree] 
    (map skl (filter seq? tree))) 

(def test_data1 '(1 (2 3) () (()) :a)) 
(def test_data2 '(1 2 (3 4) (5 (6 7 8)))) 

再帰構文。すべてのアイデアや例を指摘していただければ幸いです。

答えて

3

ジッパーライブラリを調べると、構造化されたツリーの編集が可能になる場合がありますが、オリジナルよりもあまりエレガントではありません。ループを繰り返す必要はほとんどありません。ほとんどの場合、より高次の関数があり、同じまたはより効率的に問題をよりエレガントに解決しました。

maploop ... recurに置き換えると、コードがより冗長で明確になりません。チャンクされたシーケンスの利点も失われます。

+0

ありがとうございます。あなたはClojure.zipを参照しています。私はそれについて知っている、それを使用し、この運動をしたくないと思った。 – octopusgrabbus

+0

トランポリンは、ここでも直接適用することはできませんが、ループ再発に加えて知るべき興味深い機能です。 –

4

ループと反復は単純な反復の変換です。しかしながら、樹木への下降は本質的に再帰的である。単一の反復に変換するには、スタックを手動で維持する必要があります。したがって、あなたのコードには単純な変換はありません。

+0

ありがとうございました。私はClojure.zipについて知っていますが、自分自身を回転させてスケルトンを抽出しようとしました。この例はUPennのいくつかの大学院コンピュータサイエンス演習から来ました。あなたの答えは少なくとも、これは解決するのが簡単な問題ではないと私に言った。ありがとうございました。 – octopusgrabbus

1

clojure.walkソースをご覧ください。これは、Clojureネストされたすべてのデータ構造(順序付けされたマップを除く)で(大量の)操作を実行するライブラリです。 loop/recurを使わずに、局所的に定義された無名関数による再帰を使って、非常に強力であるが、信じられないほど単純な探しているコードがある。

そこにある関数のほとんどは、ウォークウォーク関数に基づいたポストウォーク関数とプレウォーク関数に基づいています。ソースと(prewalk-demo形式)と(postwalk-demo形式)を使用すると、実行された再帰的手順についての優れた見識を得ることができます。

これがあなたの問題を解決するのに役立つかどうかは分かりませんが、私は現在、同じ問題のドメインで何かをしようとしています。ネストされたマップとベクトルをルートからリーフまでのすべてのパスのシーケンスに「フラット化」する関数を作成し、各パスにキーのシーケンスおよび/リーフ '値。

このライブラリは、全体の構造全体を再帰的に編集する価値があるようです。しかし、私はまだそれを使用して、自分の「経路」に必要な反復と、おそらくあなたの「スケルトン」問題の間に蓄積されたデータを追跡する方法を知らない。