【问题标题】:doseq Clojure returning nil, not accessing functionsdoseq Clojure 返回 nil,不访问函数
【发布时间】:2016-01-30 19:24:24
【问题描述】:

我正在尝试对序列中的每个单词通过名为transform 的函数运行每个单词,该函数将按字母顺序排序并更改为小写。但我得到的只是nil??

我猜我使用了 doseq 错误,但看起来没问题?谁能指点一下?

(defn sort-string [s]
  (apply str (sort s)))

(defn transform [word x]
  (let [x (sort-string (str/lower-case word))]
    (prn word)
    (prn word)))

(doseq [dictionary '("one" "two" "three" "FouR" "wot" "Rheet" "nope" "#")]
  (transform dictionary))

【问题讨论】:

  • doseq 总是返回 nil
  • 此外,您的转换函数需要第二个参数(名为 x),即使您从未给它任何东西,并且您会立即将 x 重新绑定到返回的值 from sort-string.

标签: clojure


【解决方案1】:

doseq 用于在迭代一系列项目时产生副作用。例如,将每个项目一个接一个地放入队列中:

(doseq [msg messages]
  (put-to-queue! msg))

它返回nil,因为它旨在用于副作用,而不是计算某些

转换一个值列表(这是你想要做的),你可以使用for,它的语法类似于doseq .也可以使用mapfiltersort等。

【讨论】:

    【解决方案2】:

    doseq 仅用于副作用,如果您希望结果为序列,可以使用for 代替,其语法与doseq 相同。

    (for [wordset '("one" "two" "three" "FouR" "wot" "Rheet" "nope" "#")]
      (transform wordset))
    => ("eno" "otw" "eehrt" "foru" "otw" "eehrt" "enop" "#")
    

    【讨论】:

    • 是的,for 将是理想的,那么使用 wordset 调用 transform for ever 是 wordset 中的字符串吗?我最理想的做法是将排序后的单词和原始单词传递到地图中
    • (into {} (for [wordset ...] ((juxt identity transform) wordset)) - 这将使用转换为每个单词集返回一个键/值对,然后将它们全部放入哈希映射中
    • 或者您是否想要为每个单词提供单独的地图?
    【解决方案3】:

    这是一个例子:

    (def words ["one" "two" "three" "FouR" "wot" "Rheet" "nope" "#"])
    (sort (map clojure.string/lower-case words))
     ;; => ("#" "four" "nope" "one" "rheet" "three" "two" "wot")
    

    【讨论】:

    • 不可能为每个字符串传递一个函数吗?因为它想让 x 成为单词的排序版本。最终,一旦我得到排序,我想将排序后的单词和原始单词都传递到地图中
    【解决方案4】:

    您的transform 函数和doseq 表达式存在问题。他们建议您不了解 Clojure 程序中如何传递信息:

    • 函数的参数按值传递,并且完全 不受评估影响。
    • let 绑定重新定义了名称。它不分配给 现有的。
    • 函数的唯一信息是它的返回值 (忽略副作用)。

    你的transform 函数

    • 不使用其x 参数
    • 打印其word 参数- 两次- 并返回nil

    并且let 绑定无效。

    你想要的是……

    (defn transform [word]
       (sort-string (clojure.string/lower-case word)))
    

    或者,更简洁地说,

     (def transform 
       (comp sort-string clojure.string/lower-case))
    

    这将返回转换后的字符串,而不会打印它。


    正如其他人所解释的,doseq 不合适。它总是返回nil。只是……

     (let [dictionary '("one" "two" "three" "FouR" "wot" "Rheet" "nope" "#")]
       (map transform dictionary))
    

    ...给...

    ("eno" "otw" "eehrt" "foru" "otw" "eehrt" "enop" "#")
    

    【讨论】:

    • 一直在编辑,截至我写答案时,我的答案转换实际上是正确的......
    猜你喜欢
    • 2017-11-25
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多