Rubyで書かれた、グラフ内のノード間の最小距離を見つける関数があります。私はそれをClojureに翻訳しましたが、私の意見ではひどいようです。
データの表現は次のようになります。
hash = {:v0 [:v1 :v2 :v3]
:v1 [:v4 :v5 :v6]
:v2 [:v7 :v8 :v9]
:v3 [:v10 :v11 :v12]
:v4 [:v13 :v14 :v15]}
Ruby関数は次のようになります。
def distance src, target, hash
return 0 if src == target
return nil if hash[src].nil?
dist = 1
if hash[src].include? target
return dist
else
arr = hash[src].map {|x| distance x, target, hash}
end
arr = arr.delete_if {|x| x.nil?}
return dist + arr.min if !arr.empty?
return nil
end
そして、Clojure関数は次のようになります。
(use 'clojure.contrib.seq-utils)
(defn distance [src target h]
(if (= src target)
0
(if (nil? (h src))
nil
(if (includes? (h src) target)
1
(let [arr (filter #(not= % nil) (map #(distance % target h) (h src)))]
(if (= (empty? arr) true)
nil
(+ 1 (apply min arr))))))))
これを行うための、よりエレガントでClojureのような方法を教えてください。それらのネストされたifはひどいです。