1

我有一个表格的数据结构["a" "b" " c" "d" " e" " f" "g"]

我想将其简化为["a" "b c" "d e f" "g"],即以空格开头的字符串连接到它们前面的字符串。

我已经为此苦苦挣扎了几个小时,正在寻找一些灵感!

4

4 回答 4

2

这会将字符串序列拆分为块,然后将所有应该连接的字符串组与string/join每个组的单个调用连接起来,因此它避免了解决方案将字符串一个一个粘贴在一起的二次行为:

(def xs ["a" "b" " c" "d" " e" " f" "g"])

(require '[clojure.string :as string])

(->> xs
     (partition-by #(.startsWith ^String % " "))
     (map vec)
     (partition-all 2)
     (reduce (fn [acc [ps ss]]
               (-> acc
                   (into (pop ps))
                   (conj (string/join "" (cons (peek ps) ss)))))
             []))
;= ["a" "b c" "d e f" "g"]

请注意,这假定第一个字符串不以空格开头。为了消除这个假设,您可以在前面添加一个空字符串((cons "" xs)而不是xs在上面,或者(cons "")作为->>第一步)来“捕捉”它们。在这种情况下,结果将以一个字符串开头,该字符串由以空格开头的序列初始字符串连接在一起,或者如果序列不以此类字符串开头,则为一个空格,因此您可以检查""第一个位置是否存在结果并可能将其过滤掉。

于 2013-08-20T13:40:18.747 回答
1

过滤器和初始累加器处理第一个的混合方法从空间案例开始。

(defn join-when-space [vs]
  (mapv (partial apply str) 
    (filter not-empty 
      (reduce (fn [a s] (if (re-find #"^\s" s) 
                          (conj (pop a) (conj (peek a) s)) 
                          (conj a [s]))) 
         [[]] vs))))
于 2013-08-20T16:03:22.173 回答
1

以下是使用 的一种方法reduce,尽管可能有一种更优雅的方法来做同样的事情 - Clojure 中经常有 :)

(defn join-when-space [v]
   (->> (reduce (fn [acc next-value]
                   (if (re-matches #"^ .*" next-value)
                     (concat (butlast acc) [(str (last acc) next-value)])
                     (concat acc [next-value]))) 
                [[] (first v)] (rest v))
         rest
         (into [])))
于 2013-08-20T13:38:49.900 回答
0

此函数生成拼接在初始空格上的序列字符串的惰性序列:

(defn spliced-seq [strings]
  (let [[x & xs] strings]
   (if (empty? xs)
    [x]
    (let [[ys & ns] (split-with #(.startsWith % " ") xs)]
      (cons (apply str x ys) (lazy-seq (f ns)))))))

然后(vec (spliced-seq) ["a" " b" " c" "d" "e"]))产生["a b c" "d e"].

于 2013-08-25T04:31:24.283 回答