【问题标题】:How to repeat string n times in idiomatic clojure way?如何以惯用的clojure方式重复字符串n次?
【发布时间】:2011-07-22 23:10:32
【问题描述】:

在 Ruby 中,"str" * 3 会给你“strstrstr”。在 Clojure 中,我能想到的最接近的是(map (fn [n] "str") (range 3)) 有没有更惯用的做法?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    这个怎么样?

    (apply str (repeat 3 "str"))
    

    或者只是

    (repeat 3 "str")
    

    如果你想要一个序列而不是一个字符串。

    【讨论】:

    • 完美!我知道必须有类似重复的东西,只是找不到它
    • 如果您有很多重复,apply 是否会达到参数计数的限制?
    【解决方案2】:

    还有一个更有趣的使用协议的替代方案:

    (defprotocol Multiply (* [this n]))
    

    接下来扩展String类:

    (extend String Multiply {:* (fn [this n] (apply str (repeat n this)))})
    

    所以您现在可以“方便地”使用:

    (* "foo" 3)
    

    【讨论】:

    • +1 表示比 clojure.contrib.string/repeat 更变态一个数量级的代码 :)
    • 有趣,但不要在家里这样做。 :)
    【解决方案3】:

    只是为了提出一些更棒的,希望能发人深省的解决方案。

    user=> (clojure.string/join (repeat 3 "str"))
    "strstrstr"
    
    user=> (format "%1$s%1$s%1$s" "str")
    "strstrstr"
    
    user=> (reduce str (take 3 (cycle ["str"])))
    "strstrstr"
    
    user=> (reduce str (repeat 3 "str"))
    "strstrstr"
    
    user=> (reduce #(.concat %1 %2) (repeat 3 "str"))
    "strstrstr"
    

    【讨论】:

    • 我还要添加:(clojure.string/join (repeatedly 3 (partial str "str")))。与第一个相似但不同。
    【解决方案4】:

    您还可以使用 clojure.contrib.string 中的重复函数。如果您使用 require 将其添加到您的命名空间,例如

    (ns myns.core (:require [clojure.contrib.string :as str]))
    

    然后

    (str/repeat 3 "hello")
    

    会给你

    "hellohellohello"
    

    【讨论】:

      【解决方案5】:

      或者使用clojure-contrib'string package自带的repeat函数。在这种情况下,您可以使用 (clojure.contrib.string/repeat 3 "str") 生成 "strstrstr"。

      【讨论】:

      • 这似乎真的很有用,但它似乎不再存在。您知道使用 Clojure 1.4 的方法吗?
      • @EricWilson clojure.contrib was mostly migrated 到语言版本 1.3 开头的其他地方。 clojure.contrib.string 已迁移到 clojure.string,它似乎不再包含“重复”。
      【解决方案6】:

      我不会声称这是惯用的,但也可以使用 clojure cl-format 函数重复字符串,该函数是 clojure 从 common lisp 继承的。 Common lisp 又从 50 年代提出这项工作的 FORTRAN 移植过来。

      我们在 2018 年...

      例子:

      user=> (cl-format nil "~v@{~a~:*~}" 5 "Bob")
      "BobBobBobBobBob"
      

      格式字符串的作用如下:

      • 第一个格式说明符是~5@{,其中五个是从参数列表中拉出的,因为@ 前面有一个v~5@{ 反过来意味着使用整个参数列表(字符串“Bob”)作为可迭代对象迭代 5 次。
      • 在花括号内(花括号表达式以~} 结尾),我们用~a 打印字符串“Bob”,然后使用~:* 构造“将参数指针”移回一个位置,这样我们可以再次“消费”论点“Bob”。

      瞧,鲍勃重复了 5 次。

      需要注意的是cl-format可以要么返回产生的字符串(如果第二个参数为nil),打印到当前的*out*(如果第二个参数是true),或者打印到一个writer(如果第二个参数是 writer)。

      有关格式字符串语法的所有细节,您可以参考:

      Formatted Output to Character Streams

      在通用 lisp 中的语言参考和可能:

      Eliminating format from lisp

      为什么有人认为cl-format 是个坏主意。

      【讨论】:

        【解决方案7】:

        单一的解决方案:(即:永远不要这样做)

        ((fn [[x & xs]] (apply (eval x) xs)) (repeat 4 'str))

        【讨论】:

        • d 投票。没有冒犯,但问题是关于“更好的方式”,而不是“混淆 clojure 竞赛”的事情......我建议你改进答案并说明为什么你的解决方案“更好”,或者将其删除到防止更多热量...
        • @Rick77 :答案中有说明:“单一解决方案”。我想投反对票是公平的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-27
        • 2010-09-21
        • 1970-01-01
        • 1970-01-01
        • 2013-10-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多