Clojure说 - 喜欢与varargs

时间:2014-12-10 08:16:02

标签: clojure

输入:“Michael”“Julia”“Joe”“Sam”

输出:嗨,迈克尔,朱莉娅,乔和萨姆。 (注意逗号和“和”这个词)

输入:nil

输出:嗨,世界。

这是我的第一次尝试:

(defn say-hi [& name]
  (print "Hi," name))


user> (say-hi "Michael")
Hi, (Michael)
nil
user> (say-hi "Michael" "Julia")
Hi, (Michael Julia)
nil

问题:

  1. 如何实现默认:(无输入,说“Hi World!”)

  2. 如何摆脱输出中名字周围的父母?

  3. 如何实现逗号分隔并添加连词“和”?

3 个答案:

答案 0 :(得分:1)

首先,Clojure支持多个arity函数,所以你可以做这样的事情来实现默认行为:

(defn say-hi
  ([] (say-hi "World"))
  ([& names] ...))

然后,您想要的是使用seq并将它们包含的所有字符串连接在一起,在它们之间使用", "clojure.string命名空间包含许多字符串操作函数,其中一个是clojure.string/join

(require '[clojure.string :as string])
(string/join ", " ["Michael", "Julia"])
;; => "Michael, Julia"

但是seq的最后一个元素应该使用" and "作为分隔符连接起来,所以你最终会得到这样的结果:

(require '[clojure.string :as string])
(defn say-hi
  ([] (say-hi "World"))
  ([& names]
   (if (next names)
     (format "Hi, %s, and %s!"
             (string/join ", " (butlast names))
             (last names))
     (format "Hi, %s!" (first names)))))

请注意,您必须区分单名称和多名称案例,(next names)基本上检查seq是否包含多个元素。 (您可以通过向函数添加另一个arity来实现相同的目标。)

(say-hi)
;; => "Hi, World!"

(say-hi "Michael")
;; => "Hi, Michael!"

(say-hi "Michael" "Julia" "Joe" "Sam")
;; => "Hi, Michael, Julia, Joe, and Sam!"

答案 1 :(得分:0)

您可以使用clojure.string/join

(use '[clojure.string :only [join]])

(defn sentencify [& elems]
  (->>
    [(join ", " (butlast elems)) (last elems)]
    (remove empty?)
    (join " and ")))

(defn say-hi [& name]
  (print "Hi," (if name
                  (sentencify name)
                  "World!")))

答案 2 :(得分:0)

简明的解决方案:

(defn say-hi [& names]
  (let [names (case (count names)
                0 ["world"]
                1 names
                (concat (butlast names) (list (str "and " (last names)))))]
    (->> names, (cons "Hi"), (interpose ", "), (apply str))))

(say-hi)
;"Hi, world"

(say-hi "Michael")
;"Hi, Michael"

(say-hi "Michael" "Julia" "Joe" "Sam")
;"Hi, Michael, Julia, Joe, and Sam"

对于names的长列表,您可能希望避开countlastbutlast,可能首先将names倾注到向量中。


要打印(如问题所示)而不是返回格式化字符串,请将print附加到最终表单:

(->> names, (cons "Hi"), (interpose ", "), (apply str), print)