将值累积到列表中

ped*_*eis 1 clojure

我想根据某些功能的结果创建一个列表.在Java(我的背景)中,我会做类似的事情:

List<String> messages = ...

if(condition 1)
   messages.add(message 1);

if(condition 2)
   messages.add(message 2);

...

if(condition N)
   messages.add(message N);
Run Code Online (Sandbox Code Playgroud)

在clojure中,我想我需要使用let如下所示创建一个列表(只是虚拟示例):

(let [result
  (vec
    (if (= 1 1) "message1" "message2")
    (if (= 1 0) "message3" "message4"))]
result)
Run Code Online (Sandbox Code Playgroud)

我也检查了cond但是我需要考虑所有的验证(cond在满足一个条件后中断)将元素附加到列表中.

我应该采用哪种方式来实现这一目标?

Car*_*ate 5

如果您希望像Java示例中那样有条件地添加它们,您可以使用cond->,它不会短路:

(let [messages []]
  (cond-> messages ; Conditionally thread through conj
    (= 1 1) (conj "Message1")
    (= 0 1) (conj "Message2")
    (= 0 0) (conj "Message3")))

=> ["Message1" "Message3"]
Run Code Online (Sandbox Code Playgroud)

如果你想像第二个例子那样有条件地添加一个或另一个,那么你可以使用plain conj和一些if表达式:

(let [messages []]
  (conj messages
    (if (= 1 1) "Message1" "Message2")
    (if (= 0 1) "Message3" "Message4")))

=> ["Message1" "Message4"]
Run Code Online (Sandbox Code Playgroud)

而且我会注意到你原来的尝试几乎奏效了.而不是vec,你可以使用vector,或只是一个矢量文字:

(let [messages [(if (= 1 1) "Message1" "Message2")
                (if (= 1 0) "Message3" "Message4")]]
  messages)

=> ["Message1" "Message4"]
Run Code Online (Sandbox Code Playgroud)

虽然,如果您还没有messages要添加的填充,这只会是有益的.如果是这种情况,您必须使用concatinto:

(let [old-messages ["old stuff"]
      messages [(if (= 1 1) "Message1" "Message2")
                (if (= 1 0) "Message3" "Message4")]]
  (into old-messages messages))

=> ["old stuff" "Message1" "Message4"]
Run Code Online (Sandbox Code Playgroud)