我已将数据建模为嵌入向量。我需要找出这些向量中是否存在元素。我有以下代码,它正确地做到了。但是,我想要一个更惯用的方法来做这个建议。
(defn exists-in-vector?
[my-vec my-sym]
(= my-sym (first my-vec)))
(defn exists-in-vectors?
[all-vectors my-symbol]
(empty? (for [first-vector all-vectors
second-vector first-vector
third-vector second-vector
:when (exists-in-vector? third-vector my-symbol)
:while (exists-in-vector? third-vector my-symbol)]
true)))
> (exists-in-vectors? [[[[:a 20] [:b :30]] [[:c 20] [:d :30]]]
[[[:h 20] [:g :30]] [[:f 20] [:e :30]]]]
:a) => true
答案 0 :(得分:9)
这是少数几个“扁平化”正是您想要的情况之一:
(def vectors [[[[:a 20] [:b :30]] [[:c 20] [:d :30]]]
[[[:h 20] [:g :30]] [[:f 20] [:e :30]]]])
(some #{:g} (flatten vectors))
;=> :g
(some #{:k} (flatten vectors))
;=> nil
顺便说一句,flatten的定义很有趣。 (来源展平)或http://clojuredocs.org/clojure_core/clojure.core/flatten:
(defn flatten "Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns nil." {:added "1.2" :static true} [x] (filter (complement sequential?) (rest (tree-seq sequential? seq x))))
答案 1 :(得分:5)
嵌套向量可以被认为是树
(def tree [[[[:a 20] [:b :30]] [[:c 20] [:d :30]]]
[[[:h 20] [:g :30]] [[:f 20] [:e :30]]]])
(some #(= :a %) (tree-seq vector? identity tree))
;=> true
(some #(= :k %) (tree-seq vector? identity tree))
;=> nil
答案 2 :(得分:1)
user=> (defn in-nested? [thing elt]
#_=> (if (vector? thing)
#_=> (boolean (some #(in-nested? % elt) thing))
#_=> (= thing elt)))
#'user/in-nested?
user=> (def data [[[[:a 20] [:b :30]] [[:c 20] [:d :30]]] [[[:h 20] [:g :30]] [[:f 20] [:e :30]]]])
#'user/data
user=> (in-nested? data :a)
true
user=> (in-nested? data :c)
true
user=> (in-nested? data :z)
false
user=> (in-nested? data 20)
true
user=> (in-nested? data 40)
false