clojure when-let替代空数组?

时间:2014-11-04 11:27:43

标签: clojure

我在clojure中尽可能地生成json。我的问题是,只有给定给定的参数,json的某些分支才会出现。以下是这种情况的样本

(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可以实现同样的效果,但它不起作用,因为我的地图返回[]而不是nil。

(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}))}}})

任何想法,如果我可以以某种方式制作时 - 让我们将空列表/数组/ seq视为假,这样我可以稍微清理一下我的代码?

2 个答案:

答案 0 :(得分:3)

如果

not-empty不为空,则返回其参数。

when-let与集合一起使用时,请始终使用not-empty

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

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

在你的情况下,我更喜欢这样的事情:

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

请注意,上面列出的所有三个优点都符合,没有嵌套let

还要注意一个新的优势

  • 在更多条件下更容易扩展

答案 1 :(得分:1)

seq在空输入序列上返回nil,因此您可以执行:

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