【问题标题】:Need help for substituting name in string problem (clojure)需要帮助在字符串问题中替换名称(clojure)
【发布时间】:2021-03-04 19:47:07
【问题描述】:

我正在为 Clojure 做一个练习题。它应该很简单,但它实际上让我很头疼。 问题描述如下:

Two-fer 或 2-fer 是二合一的缩写。一份给你,一份给我。 给定一个名称,返回一个带有消息的字符串:“一个给 X,一个给我。” 其中 X 是给定的名称。 但是,如果缺少名称,则返回字符串:“一个给你,一个给我。”

这是我尝试过的:

(defn two-fer [& name]
  (if (nil? name)
    "One for you, one for me."
    (str "One for " name ", one for me."
  )
)

但是,我最终得到了以下单元测试输出:

预期:(=“一个给 Bob,一个给我。”(two-fer/two-fer “Bob”)) 实际:(not (= "一个给 Bob,一个给我。" "一个给 ("Bob"),一个给我。"))

lein test :only two-fer-test/name-alice-test

(name-alice-test)失败(two_fer_test.clj:9) 预期:(=“爱丽丝一个,我一个。”(二费/二费“爱丽丝”)) 实际:(not (= "一个给 Alice,一个给我。" "一个给 ("Alice"),一个给我。"))

(two-fer-test) 中的错误 (two_fer.clj:5) 预期:(=“一个给你,一个给我。”(二费/二费)) 实际:java.lang.ClassCastException:类 java.lang.String 无法转换为类 clojure.lang.IFn(java.lang.String 位于加载程序“bootstrap”的模块 java.base 中;clojure.lang.IFn 未命名加载器'app'的模块)

我也试过了:

(defn two-fer [& name]
  (str "One for " (if (nil? name) "you" name) ", one for me.")
)
(defn two-fer [& name]
  (if (nil? name)
    "One for you, one for me."
    (eval `(str "One for " ~name ", one for me.")
  )
)
(defn two-fer [& name]
  (if nil? name)
    "One for you, one for me."
    (clojure.string/replace (str "One for " name ", one for me.") #"\\(?\\"\\)" ""))
  )
)

【问题讨论】:

    标签: java clojure


    【解决方案1】:

    你可以编写多参数函数:

    (defn two-fer
      ([] (two-fer "you"))
      ([name] (str "One for " name ", one for me.")))
    

    【讨论】:

      【解决方案2】:

      问题在于& 符号,它将任意数量的参数包装到一个列表/序列中。

      你可能需要这样的东西:

      (defn two-fer
        [& args]
        (let [name (if (empty? args)
                     "you"
                     (first args))]
          (str "One for " name ", one for me.")))
      

      结果

      (two-fer "Bob")  => "One for Bob, one for me."
      (two-fer)        => "One for you, one for me."
      

      您可能也对此list of documentation sources感兴趣。

      【讨论】:

        【解决方案3】:
        (defn two-fer [& names]
          (str "One for " (if (empty? names) "you" (first names)) ", and one for me."))
        
        ;; or using `or` (old lisp style, not Clojure's best practice):
        (defn two-fer [& names]
          (str "One for " (or (first names) "you") ", and one for me."))
        

        【讨论】:

          【解决方案4】:

          在这种情况下,我总是选择two-arity version。然而你的 如果您要解构“其余”参数中的第一个,则示例几乎可以工作。

          (defn two-fer
            [& [name]]
            (if (nil? name)
              "One for you, one for me."
              (str "One for " name ", one for me.")))
          
          (println (two-fer) (two-fer "Bob"))
          ; → One for you, one for me. One for Bob, one for me.
          

          【讨论】:

          • (format "One for %s, one for me." (or name "you"))
          • (str "One for " (or name "you") ", one for me.")
          【解决方案5】:

          重写它以处理您传递给它的所有名称:

          (defn two-fer [& names]
            (if (nil? names)
              "One for you, one for me."
              (str "One for " (apply str (interpose ", " names)) ", one for me.")
            )
          )
          

          测试如下:

          user=> (two-fer)
          "One for you, one for me."
          user=> (two-fer "John")
          "One for John, one for me."
          user=> (two-fer "John" "Paul" "George" "Ringo")
          "One for John, Paul, George, Ringo, one for me."
          

          编辑

          因为没有像杀戮一样的杀戮:

          (defn two-fer [& names]
            (let [all-names (conj (if (nil? names) ["you"] (vec names)) "me")
                  comma     (if (< (count all-names) 2) ", " ", one for ")]
              (str "One for "  (apply str (interpose comma all-names)))
            )
          )
          

          测试结果:

          user=> (two-fer)
          "One for you, one for me"
          user=> (two-fer "John")
          "One for John, one for me"
          user=> (two-fer "John" "Paul" "George" "Ringo")
          "One for John, one for Paul, one for George, one for Ringo, one for me"
          

          【讨论】:

            猜你喜欢
            • 2015-12-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-03-14
            • 1970-01-01
            • 2016-01-29
            • 1970-01-01
            相关资源
            最近更新 更多