在Clojure中以最大值分割矢量 - 更好的方法?

Mal*_*rik 5 clojure

新手问题:

如何在数字矢量中包含最大值的第一个实例并将其包括在内?

所以,从此[1 2 3 4 5 4 3 2 1],得到[1 2 3 4 5] [4 3 2 1].

我这样做的方式似乎过于复杂:

(def up5 [1 2 3 4 5 4 3 2 1])
(split-at (inc (.indexOf up5 (apply max up5))) up5) ; => [1 2 3 4 5] [4 3 2 1]
Run Code Online (Sandbox Code Playgroud)

这看起来有点尴尬吗?例如,使用定义的向量三次.我们是否需要使用Java来获取索引?

什么是更好,更惯用或更高效的方式?

谢谢.

小智 1

(defn split-at-max [v]
  (when (seq v)
    (let [m (apply max v)
          point (inc (count (reduce (fn [a b] (if (> m b) (conj a b) 
                                              (reduced a))) [] v)))]
      ((juxt #(take point %) #(drop point %)) v))))

(split-at-max [1 2 9 2 -7  33 3 4 53 1 22 4 -44 444 3 2 3 0 -21])
;;=> [(1 2 9 2 -7 33 3 4 53 1 22 4 -44 444) (3 2 3 0 -21)]
(split-at-max [])
;;=> nil
(split-at-max [26 27 28 29 30 31 32 33])
;;=> [(26 27 28 29 30 31 32 33) ()]
(split-at-max [33 32 31 30 29 28 27 26])
;;=> [(33) (32 31 30 29 28 27 26)]
;; works also with sets and lists:
(split-at-max '(1 2 9 2 -7  33 3 4 53 1 22 4 -44 444 3 2 3 0 -21))
;;=> [(1 2 9 2 -7 33 3 4 53 1 22 4 -44 444) (3 2 3 0 -21)]
(split-at-max '())
;;=> nil
(split-at-max (hash-set))
;;=> nil
(split-at-max (sorted-set))
;;=> nil
(split-at-max (sorted-set 1 2 9 2 -7 33 3 4 53 1 22 4 -44 444 3 2 3 0 -21))
;;=> [(-44 -21 -7 0 1 2 3 4 9 22 33 53 444) ()]
(split-at-max (hash-set 1 2 9 2 -7 33 3 4 53 1 22 4 -44 444 3 2 3 0 -21))
;;=> [(0 1 4 -21 33 22 -44 3 2 444) (-7 9 53)]
Run Code Online (Sandbox Code Playgroud)

另一种类似的方法是使用split-with在最大点处进行分割(seq如果有可能有空集合,还需要首先对输入进行操作):

(let [v [1 2 9 2 -7 33 3 4 53 1 22 4 -44 444 3 2 3 0 -21]
      m (apply max v)]
  ((juxt #(concat (first %) [(first (second %))]) #(rest (second %)))
   (split-with (partial > m) v)))
;;=> [(1 2 9 2 -7 33 3 4 53 1 22 4 -44 444) (3 2 3 0 -21)]
Run Code Online (Sandbox Code Playgroud)