2014-11-04 50 views
2

我正在生成json,就像我可以在clojure中一样。我的问题是,只有给定参数时,json的某些分支才存在。这是一个这样的条件的样本clojure when-let替代一个空阵列?

(defn message-for 
    [name uuid & [generated-uuids]] 
    {:message {:id    (generate-uuid) 
      :details  {:name name} 
      :metadata  {:batch (merge {:id uuid} 
              (when generated-uuids (let [batches (map #(array-map :id %) generated-uuids)] 
                      {:generatedBatches batches})))}}}) 

不幸的是,当/让部分是相当丑陋的。这同样可以通过使用when-let来实现,但不起作用,因为我的地图返回[]而不是零。

(defn message-for 
    [name uuid & [generated-uuids]] 
    {:message {:id    (generate-uuid) 
      :details  {:name name} 
      :metadata  {:batch (merge {:id uuid} 
              (when-let [batches (map #(array-map :id %) generated-uuids)] 
                  {:generatedBatches batches}))}}}) 

任何想法,如果我能以某种方式使时,让考虑空单/数组/序列为假,所以我可以清理我的代码位?

+0

很明显,你知道:generatedBatches键将不会被创建,如果产生-的UUID是空的。你在第一个解决方案中检查generated-uuids的空白。所以,你可以使你的第一个解决方案缩短为这样(当(seq generated-uuids) {:generatedBatches(map#(array-map:id%)generated-uuids)}) – mavbozo 2014-11-04 11:51:49

回答

1

seq返回nil上的空输入序列,所以你可以这样做:

(when-let [batches (seq (map #(array-map :id %) generated-uuids))] 
      {:generatedBatches batches}))}}}) 
3

not-empty返回它的参数,如果它不是空的。

当使用when-let与集合,总是使用not-empty

  • 保留集合类型
  • 使得重构更加容易
  • expressivenes

    (when-let [batches (not-empty (map ...))] 
        ...) 
    

在你的情况我但是,但是,优先[R是这样的:

... 
:metadata {:batch (cond-> {:id uuid} 
         (seq generated-uuids) 
         (assoc :generatedBatches (map ...)))} 
... 

注意,这三个以上,其中满足上市的优势,没有一个嵌套let

还注意到一个新优势

  • 更轻松地与多个条件延长lateron