代码之家  ›  专栏  ›  技术社区  ›  Hoopes

Clojure字符串分区列表,累加结果

  •  2
  • Hoopes  · 技术社区  · 7 年前

    我很抱歉标题不够精确,但这可能说明我缺乏clojure的经验。

    我试图获取一个大的字符串列表,并将该列表转换为另一个字符串列表,同时进行连接,直到累加器小于某个长度。

    例如,如果我有

    [ "a" "bc" "def" "ghij" ]
    

    我的最大字符串长度是4,我会沿着列表走下去,累加concat,直到累加len>4,然后从头启动蓄能器。我的结果如下:

    [ "abc" "def" "ghij" ]
    

    我似乎想不出合适的咒语 partition-by ,这让我有点疯狂。我一直想让我的累加器 atom (但似乎不知道去哪里 reset! ),但除此之外,我不知道在哪里/如何跟踪我累积的字符串。

    提前感谢所有怜悯我的人。

    4 回复  |  直到 7 年前
        1
  •  2
  •   miner49r    7 年前
    (defn catsize [limit strs]
      (reduce (fn [res s]
                  (let [base (peek res)]
                    (if (> (+ (.length ^String base) (.length ^String s)) limit)
                      (conj res s)
                      (conj (pop res) (str base s)))))
              (if (seq strs) [(first strs)] [])
              (rest strs)))
    
        2
  •  2
  •   Igor Kharin    7 年前

    以下是我的看法:

    (defn collapse [maxlen xs]
      (let [concats (take-while #(< (count %) maxlen) (reductions str xs))]
        (cons (last concats) (drop (count concats) xs))))
    (collapse 4 ["a" "bc" "def" "ghij"])
    ;; => ("abc" "def" "ghij")
    
        3
  •  1
  •   dpassen    7 年前

    这非常接近。我不知道为什么在最后一个字符串的末尾有j。

    (sequence
     (comp
      (mapcat seq)
      (partition-all 3)
      (map clojure.string/join))
     ["a" "bc" "def" "ghij"]) => ("abc" "def" "ghi" "j")
    
        4
  •  -4
  •   Alan Thompson    7 年前

    我会这样做:

    (ns tst.demo.core
      (:use demo.core tupelo.core tupelo.test))
    
    (def bound 4)
    
    (defn catter [strings-in]
      (loop [merged-strs    []
             curr-merge     (first strings-in)
             remaining-strs (rest strings-in)]
       ;(newline) (spyx [merged-strs curr-merge remaining-strs])
        (if (empty? remaining-strs)
          (conj merged-strs curr-merge)
          (let          ; try using 'let-spy' instead
            [new-str   (first remaining-strs)
             new-merge (str curr-merge new-str)]
            (if (< (count new-merge) bound)
              (recur merged-strs new-merge (rest remaining-strs))
              (recur (conj merged-strs curr-merge) new-str (rest remaining-strs)))))))
    
    (dotest
      (is=  ["abc" "def" "ghij"]     (catter ["a" "bc" "def" "ghij"]) )
      (is=  ["abc" "def" "ghij"]     (catter ["a" "b" "c" "def" "ghij"]) )
      (is=  ["abc" "def" "ghij"]     (catter ["a" "b" "c" "d" "ef" "ghij"]) )
      (is=  ["abc" "def" "ghij"]     (catter ["a" "bc" "d" "ef" "ghij"]) )
      (is=  ["abc" "def" "ghij"]     (catter ["a" "bc" "d" "e" "f" "ghij"]) )
    
      (is=  ["abc" "def" "gh" "ij"]  (catter ["abc" "d" "e" "f" "gh" "ij"]) )
      (is=  ["abc" "def" "ghi" "j"]  (catter ["abc" "d" "e" "f" "ghi" "j"]) )
    
      (is=  ["abcdef" "ghi" "j"]     (catter ["abcdef" "ghi" "j"]) )
      (is=  ["abcdef" "ghi" "j"]     (catter ["abcdef" "g" "h" "i" "j"]) )
    )
    

    您需要添加 [tupelo "0.9.71"] 项目依赖关系。


    更新:

    spy let-spy ,您可以看到算法用于获得结果的过程。例如:

    (catter ["a" "b" "c" "d" "ef" "ghij"]) )   =>     ["abc" "def" "ghij"]     
    
    -----------------------------------------------------------------------------
    strings-in => ["a" "b" "c" "d" "ef" "ghij"]
    
    [merged-strs curr-merge remaining-strs] => [[] "a" ("b" "c" "d" "ef" "ghij")]
    new-str => "b"
    new-merge => "ab"
    
    [merged-strs curr-merge remaining-strs] => [[] "ab" ("c" "d" "ef" "ghij")]
    new-str => "c"
    new-merge => "abc"
    
    [merged-strs curr-merge remaining-strs] => [[] "abc" ("d" "ef" "ghij")]
    new-str => "d"
    new-merge => "abcd"
    
    [merged-strs curr-merge remaining-strs] => [["abc"] "d" ("ef" "ghij")]
    new-str => "ef"
    new-merge => "def"
    
    [merged-strs curr-merge remaining-strs] => [["abc"] "def" ("ghij")]
    new-str => "ghij"
    new-merge => "defghij"
    
    [merged-strs curr-merge remaining-strs] => [["abc" "def"] "ghij" ()]
    
    Ran 2 tests containing 10 assertions.
    0 failures, 0 errors.