Список разделения Clojure последовательностей, накапливая результат

Я сожалею об отсутствии точности в названии, но это могло бы иллюстрировать мое отсутствие опыта clojure.

Я пытаюсь взять большой список последовательностей и новообращенного, которые перечисляют в другой список последовательностей, связывая, когда я иду, пока сумматор не меньше, чем некоторая длина.

Например, если я имею

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

and my max string length is 4, I would walk down the list, accumulating the concat, until my accumulation len > 4, and then start the accumulator from scratch. My result would look like:

[ "abc" "def" "ghij" ]

Я, может казаться, не придумываю надлежащее колдовство для разделение - , и это сводит меня с ума немного. Я пытался сделать свой сумматор атом (но, может казаться, не выясняет, где сброс! ), но кроме этого, я не вижу, где/как отслеживать мою накопленную последовательность.

Заранее спасибо любому щадящему меня.

1
Была некоторая неуверенность относительно ваших точных требований. Не могли бы Вы посмотреть на тесты единицы, включенные в мой ответ, и проверить, что это - поведение, которое вы искали? Спасибо.
добавлено автор Alan Thompson, источник
Была некоторая неуверенность относительно ваших точных требований. Не могли бы Вы посмотреть на тесты единицы, включенные в мой ответ, и проверить, что это - поведение, которое вы искали? Спасибо.
добавлено автор Alan Thompson, источник
Благодаря всем респондентам - I' m sitll использующий все предложения в качестве полезного опыта, и примет ответ, когда/если я когда-либо пойму. Еще раз спасибо!
добавлено автор Hoopes, источник

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"]) )
)

Необходимо будет добавить [ниссу "0.9.71"] к зависимостям проекта.


Обновление:

Если вы пользователь шпион и позволенный шпион , вы видите процесс использование алгоритма, чтобы прибыть в результат. Например:

(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.
4
добавлено

Вот то, как я сделал бы это:

(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"]) )
)

Необходимо будет добавить [ниссу "0.9.71"] к зависимостям проекта.


Обновление:

Если вы пользователь шпион и позволенный шпион , вы видите процесс использование алгоритма, чтобы прибыть в результат. Например:

(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.
4
добавлено
(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
добавлено
(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
добавлено

Вот мое взятие на этом:

(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")
2
добавлено
подход правилен, но он работает на всякий случай, подпоследовательность находится в начале входа. Потерпел бы неудачу для (крах 4 ["a" "до н.э" "определение" "ghij" "z" "xc" "vbn"]) => ("ABC" "определение" "ghij" "z" "xc" "vbn") или (крах 4 ["asdf" "до н.э" "определение" "ghij"]) => (ноль "asdf" "a" "до н.э" "определение" "ghij") .. Это должно быть зафиксировано так или иначе))),
добавлено автор leetwinski, источник

Вот мое взятие на этом:

(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")
2
добавлено
подход правилен, но он работает на всякий случай, подпоследовательность находится в начале входа. Потерпел бы неудачу для (крах 4 ["a" "до н.э" "определение" "ghij" "z" "xc" "vbn"]) => ("ABC" "определение" "ghij" "z" "xc" "vbn") или (крах 4 ["asdf" "до н.э" "определение" "ghij"]) => (ноль "asdf" "a" "до н.э" "определение" "ghij") .. Это должно быть зафиксировано так или иначе))),
добавлено автор leetwinski, источник

Это становится достаточно близким. Я не уверен, почему у вас есть j в конце заключительной последовательности.

(sequence
 (comp
  (mapcat seq)
  (partition-all 3)
  (map clojure.string/join))
 ["a" "bc" "def" "ghij"]) => ("abc" "def" "ghi" "j")
1
добавлено
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Clojure — русскоговорящее сообщество
Clojure — русскоговорящее сообщество
433 участник(ов)

Общаемся на темы, посвященный Clojure. Решаем проблемы, обмениваемся опытом и делимся новостями. Вакансии и поиск работы: @clojure_jobs Вам могут быть интересны: @javascript_ru, @nodejs_ru, @ruby_ru, @devops_ru, @devops_jobs